mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-01-03 05:10:12 +02:00
making search work (finally)
This commit is contained in:
parent
c2b5577cba
commit
0bf278e72f
@ -230,7 +230,7 @@ impl Grep {
|
|||||||
|
|
||||||
fn find_line_end(&self, buf: &[u8], pos: usize) -> usize {
|
fn find_line_end(&self, buf: &[u8], pos: usize) -> usize {
|
||||||
memchr(self.opts.line_terminator, &buf[pos..])
|
memchr(self.opts.line_terminator, &buf[pos..])
|
||||||
.map_or(buf.len(), |i| pos + i)
|
.map_or(buf.len(), |i| pos + i + 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,7 +281,7 @@ mod tests {
|
|||||||
let start = memrchr(b'\n', &haystack[..s])
|
let start = memrchr(b'\n', &haystack[..s])
|
||||||
.map_or(0, |i| i + 1);
|
.map_or(0, |i| i + 1);
|
||||||
let end = memchr(b'\n', &haystack[e..])
|
let end = memchr(b'\n', &haystack[e..])
|
||||||
.map_or(haystack.len(), |i| e + i);
|
.map_or(haystack.len(), |i| e + i + 1);
|
||||||
lines.push(Match {
|
lines.push(Match {
|
||||||
start: start,
|
start: start,
|
||||||
end: end,
|
end: end,
|
||||||
|
65
src/main.rs
65
src/main.rs
@ -4,6 +4,9 @@ extern crate crossbeam;
|
|||||||
extern crate docopt;
|
extern crate docopt;
|
||||||
extern crate env_logger;
|
extern crate env_logger;
|
||||||
extern crate grep;
|
extern crate grep;
|
||||||
|
#[cfg(test)]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate memchr;
|
extern crate memchr;
|
||||||
@ -136,7 +139,7 @@ fn run(mut args: Args) -> Result<()> {
|
|||||||
}
|
}
|
||||||
let args = Arc::new(args);
|
let args = Arc::new(args);
|
||||||
let mut workers = vec![];
|
let mut workers = vec![];
|
||||||
let stdout = Arc::new(Mutex::new(io::BufWriter::new(io::stdout())));
|
let out = Arc::new(Mutex::new(Out::new(args.clone(), io::stdout())));
|
||||||
|
|
||||||
let mut chan_work_send = {
|
let mut chan_work_send = {
|
||||||
let (worker, stealer) = chase_lev::deque();
|
let (worker, stealer) = chase_lev::deque();
|
||||||
@ -146,7 +149,7 @@ fn run(mut args: Args) -> Result<()> {
|
|||||||
.case_insensitive(args.flag_ignore_case);
|
.case_insensitive(args.flag_ignore_case);
|
||||||
let worker = Worker {
|
let worker = Worker {
|
||||||
args: args.clone(),
|
args: args.clone(),
|
||||||
stdout: stdout.clone(),
|
out: out.clone(),
|
||||||
chan_work: stealer.clone(),
|
chan_work: stealer.clone(),
|
||||||
inpbuf: InputBuffer::new(),
|
inpbuf: InputBuffer::new(),
|
||||||
outbuf: Some(vec![]),
|
outbuf: Some(vec![]),
|
||||||
@ -200,6 +203,26 @@ impl Args {
|
|||||||
ig.ignore_hidden(!self.flag_hidden);
|
ig.ignore_hidden(!self.flag_hidden);
|
||||||
walk::Iter::new(ig, wd)
|
walk::Iter::new(ig, wd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn before_context(&self) -> usize {
|
||||||
|
if self.flag_context > 0 {
|
||||||
|
self.flag_context
|
||||||
|
} else {
|
||||||
|
self.flag_before_context
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn after_context(&self) -> usize {
|
||||||
|
if self.flag_context > 0 {
|
||||||
|
self.flag_context
|
||||||
|
} else {
|
||||||
|
self.flag_after_context
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_context(&self) -> bool {
|
||||||
|
self.before_context() > 0 || self.after_context() > 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Message<T> {
|
enum Message<T> {
|
||||||
@ -209,7 +232,7 @@ enum Message<T> {
|
|||||||
|
|
||||||
struct Worker {
|
struct Worker {
|
||||||
args: Arc<Args>,
|
args: Arc<Args>,
|
||||||
stdout: Arc<Mutex<io::BufWriter<io::Stdout>>>,
|
out: Arc<Mutex<Out<io::Stdout>>>,
|
||||||
chan_work: Stealer<Message<PathBuf>>,
|
chan_work: Stealer<Message<PathBuf>>,
|
||||||
inpbuf: InputBuffer,
|
inpbuf: InputBuffer,
|
||||||
outbuf: Option<Vec<u8>>,
|
outbuf: Option<Vec<u8>>,
|
||||||
@ -245,21 +268,43 @@ impl Worker {
|
|||||||
searcher = searcher.count(self.args.flag_count);
|
searcher = searcher.count(self.args.flag_count);
|
||||||
searcher = searcher.line_number(self.args.flag_line_number);
|
searcher = searcher.line_number(self.args.flag_line_number);
|
||||||
searcher = searcher.invert_match(self.args.flag_invert_match);
|
searcher = searcher.invert_match(self.args.flag_invert_match);
|
||||||
searcher = searcher.after_context(
|
searcher = searcher.after_context(self.args.after_context());
|
||||||
self.args.flag_after_context);
|
searcher = searcher.before_context(self.args.before_context());
|
||||||
searcher = searcher.before_context(
|
|
||||||
self.args.flag_before_context);
|
|
||||||
if let Err(err) = searcher.run() {
|
if let Err(err) = searcher.run() {
|
||||||
eprintln!("{}", err);
|
eprintln!("{}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let outbuf = printer.into_inner();
|
let outbuf = printer.into_inner();
|
||||||
if !outbuf.is_empty() {
|
if !outbuf.is_empty() {
|
||||||
let mut stdout = self.stdout.lock();
|
let mut out = self.out.lock();
|
||||||
let _ = stdout.write_all(&outbuf);
|
out.write_file_matches(&outbuf);
|
||||||
let _ = stdout.flush();
|
|
||||||
}
|
}
|
||||||
self.outbuf = Some(outbuf);
|
self.outbuf = Some(outbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Out<W: io::Write> {
|
||||||
|
args: Arc<Args>,
|
||||||
|
wtr: io::BufWriter<W>,
|
||||||
|
printed: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<W: io::Write> Out<W> {
|
||||||
|
fn new(args: Arc<Args>, wtr: W) -> Out<W> {
|
||||||
|
Out {
|
||||||
|
args: args,
|
||||||
|
wtr: io::BufWriter::new(wtr),
|
||||||
|
printed: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_file_matches(&mut self, buf: &[u8]) {
|
||||||
|
if self.printed && self.args.has_context() {
|
||||||
|
let _ = self.wtr.write_all(b"--\n");
|
||||||
|
}
|
||||||
|
let _ = self.wtr.write_all(buf);
|
||||||
|
let _ = self.wtr.flush();
|
||||||
|
self.printed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -65,7 +65,9 @@ impl<W: io::Write> Printer<W> {
|
|||||||
self.write(b":");
|
self.write(b":");
|
||||||
}
|
}
|
||||||
self.write(&buf[start..end]);
|
self.write(&buf[start..end]);
|
||||||
self.write(b"\n");
|
if buf[start..end].last() != Some(&b'\n') {
|
||||||
|
self.write(b"\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn context<P: AsRef<Path>>(
|
pub fn context<P: AsRef<Path>>(
|
||||||
@ -83,11 +85,13 @@ impl<W: io::Write> Printer<W> {
|
|||||||
self.write(b"-");
|
self.write(b"-");
|
||||||
}
|
}
|
||||||
self.write(&buf[start..end]);
|
self.write(&buf[start..end]);
|
||||||
self.write(b"\n");
|
if buf[start..end].last() != Some(&b'\n') {
|
||||||
|
self.write(b"\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn binary_matched<P: AsRef<Path>>(&mut self, path: P) {
|
pub fn binary_matched<P: AsRef<Path>>(&mut self, path: P) {
|
||||||
wln!(&mut self.wtr, "binary file {} matches", path.as_ref().display());
|
wln!(&mut self.wtr, "Binary file {} matches", path.as_ref().display());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&mut self, buf: &[u8]) {
|
fn write(&mut self, buf: &[u8]) {
|
||||||
|
476
src/search.rs
476
src/search.rs
@ -164,6 +164,9 @@ impl<'a, R: io::Read, W: io::Write> Searcher<'a, R, W> {
|
|||||||
let upto = self.inp.lastnl;
|
let upto = self.inp.lastnl;
|
||||||
self.print_after_context(upto);
|
self.print_after_context(upto);
|
||||||
if !try!(self.fill()) {
|
if !try!(self.fill()) {
|
||||||
|
if self.inp.is_binary {
|
||||||
|
self.printer.binary_matched(self.path);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
while self.inp.pos < self.inp.lastnl {
|
while self.inp.pos < self.inp.lastnl {
|
||||||
@ -195,7 +198,7 @@ impl<'a, R: io::Read, W: io::Write> Searcher<'a, R, W> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if matched {
|
if matched {
|
||||||
self.inp.pos = self.last_match.end() + 1;
|
self.inp.pos = self.last_match.end();
|
||||||
} else {
|
} else {
|
||||||
self.inp.pos = self.inp.lastnl;
|
self.inp.pos = self.inp.lastnl;
|
||||||
}
|
}
|
||||||
@ -220,7 +223,7 @@ impl<'a, R: io::Read, W: io::Write> Searcher<'a, R, W> {
|
|||||||
} else {
|
} else {
|
||||||
self.last_printed = 0;
|
self.last_printed = 0;
|
||||||
}
|
}
|
||||||
if keep_from < self.last_line {
|
if keep_from <= self.last_line {
|
||||||
self.last_line = self.last_line - keep_from;
|
self.last_line = self.last_line - keep_from;
|
||||||
} else {
|
} else {
|
||||||
self.count_lines(keep_from);
|
self.count_lines(keep_from);
|
||||||
@ -240,7 +243,7 @@ impl<'a, R: io::Read, W: io::Write> Searcher<'a, R, W> {
|
|||||||
if !self.count {
|
if !self.count {
|
||||||
self.print_match(start, end);
|
self.print_match(start, end);
|
||||||
}
|
}
|
||||||
self.inp.pos = end + 1;
|
self.inp.pos = end;
|
||||||
self.match_count += 1;
|
self.match_count += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -251,14 +254,14 @@ impl<'a, R: io::Read, W: io::Write> Searcher<'a, R, W> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let start = self.last_printed;
|
let start = self.last_printed;
|
||||||
let end = upto.saturating_sub(1);
|
let end = upto;
|
||||||
if start >= end {
|
if start >= end {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let before_context_start =
|
let before_context_start =
|
||||||
start + start_of_previous_lines(
|
start + start_of_previous_lines(
|
||||||
&self.inp.buf[start..],
|
&self.inp.buf[start..],
|
||||||
end - start,
|
end - start - 1,
|
||||||
self.before_context);
|
self.before_context);
|
||||||
let mut it = IterLines::new(before_context_start);
|
let mut it = IterLines::new(before_context_start);
|
||||||
while let Some((s, e)) = it.next(&self.inp.buf[..end]) {
|
while let Some((s, e)) = it.next(&self.inp.buf[..end]) {
|
||||||
@ -286,24 +289,22 @@ impl<'a, R: io::Read, W: io::Write> Searcher<'a, R, W> {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn print_match(&mut self, start: usize, end: usize) {
|
fn print_match(&mut self, start: usize, end: usize) {
|
||||||
let last_printed = cmp::min(end + 1, self.inp.lastnl);
|
|
||||||
self.print_separator(start);
|
self.print_separator(start);
|
||||||
self.count_lines(start);
|
self.count_lines(start);
|
||||||
self.add_line(last_printed);
|
self.add_line(end);
|
||||||
self.printer.matched(
|
self.printer.matched(
|
||||||
&self.path, &self.inp.buf, start, end, self.line_count);
|
&self.path, &self.inp.buf, start, end, self.line_count);
|
||||||
self.last_printed = last_printed;
|
self.last_printed = end;
|
||||||
self.after_context_remaining = self.after_context;
|
self.after_context_remaining = self.after_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn print_context(&mut self, start: usize, end: usize) {
|
fn print_context(&mut self, start: usize, end: usize) {
|
||||||
let last_printed = cmp::min(end + 1, self.inp.lastnl);
|
|
||||||
self.count_lines(start);
|
self.count_lines(start);
|
||||||
self.add_line(last_printed);
|
self.add_line(end);
|
||||||
self.printer.context(
|
self.printer.context(
|
||||||
&self.path, &self.inp.buf, start, end, self.line_count);
|
&self.path, &self.inp.buf, start, end, self.line_count);
|
||||||
self.last_printed = last_printed;
|
self.last_printed = end;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@ -424,6 +425,7 @@ impl InputBuffer {
|
|||||||
&mut self.buf[self.end..self.end + self.read_size]));
|
&mut self.buf[self.end..self.end + self.read_size]));
|
||||||
if self.first {
|
if self.first {
|
||||||
if is_binary(&self.buf[self.end..self.end + n]) {
|
if is_binary(&self.buf[self.end..self.end + n]) {
|
||||||
|
self.is_binary = true;
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -435,10 +437,6 @@ impl InputBuffer {
|
|||||||
self.lastnl = self.end;
|
self.lastnl = self.end;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// We know there is no nl between self.start..self.end since:
|
|
||||||
// 1) If this is the first iteration, then any bytes preceding
|
|
||||||
// self.end do not contain nl by construction.
|
|
||||||
// 2) Subsequent iterations only occur if no nl could be found.
|
|
||||||
self.lastnl =
|
self.lastnl =
|
||||||
memrchr(b'\n', &self.buf[self.end..self.end + n])
|
memrchr(b'\n', &self.buf[self.end..self.end + n])
|
||||||
.map(|i| self.end + i + 1)
|
.map(|i| self.end + i + 1)
|
||||||
@ -495,6 +493,8 @@ impl IterLines {
|
|||||||
|
|
||||||
/// Return the start and end position of the next line in the buffer. The
|
/// Return the start and end position of the next line in the buffer. The
|
||||||
/// buffer given should be the same on every call.
|
/// buffer given should be the same on every call.
|
||||||
|
///
|
||||||
|
/// The range returned includes the new line.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn next(&mut self, buf: &[u8]) -> Option<(usize, usize)> {
|
fn next(&mut self, buf: &[u8]) -> Option<(usize, usize)> {
|
||||||
match memchr(b'\n', &buf[self.pos..]) {
|
match memchr(b'\n', &buf[self.pos..]) {
|
||||||
@ -509,8 +509,8 @@ impl IterLines {
|
|||||||
}
|
}
|
||||||
Some(end) => {
|
Some(end) => {
|
||||||
let start = self.pos;
|
let start = self.pos;
|
||||||
let end = self.pos + end;
|
let end = self.pos + end + 1;
|
||||||
self.pos = end + 1;
|
self.pos = end;
|
||||||
Some((start, end))
|
Some((start, end))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -532,7 +532,7 @@ fn start_of_previous_lines(
|
|||||||
mut end: usize,
|
mut end: usize,
|
||||||
mut count: usize,
|
mut count: usize,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
if buf.is_empty() {
|
if buf[..end].is_empty() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
@ -567,6 +567,9 @@ fn start_of_previous_lines(
|
|||||||
count -= 1;
|
count -= 1;
|
||||||
end = i;
|
end = i;
|
||||||
if end == 0 {
|
if end == 0 {
|
||||||
|
if buf[end] == b'\n' && count == 0 {
|
||||||
|
end += 1;
|
||||||
|
}
|
||||||
return end;
|
return end;
|
||||||
}
|
}
|
||||||
end -= 1;
|
end -= 1;
|
||||||
@ -591,6 +594,32 @@ mod tests {
|
|||||||
|
|
||||||
use super::{InputBuffer, Searcher, start_of_previous_lines};
|
use super::{InputBuffer, Searcher, start_of_previous_lines};
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref SHERLOCK: &'static str = "\
|
||||||
|
For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||||
|
Holmeses, success in the province of detective work must always
|
||||||
|
be, to a very large extent, the result of luck. Sherlock Holmes
|
||||||
|
can extract a clew from a wisp of straw or a flake of cigar ash;
|
||||||
|
but Doctor Watson has to have it taken out for him and dusted,
|
||||||
|
and exhibited clearly, with a label attached.\
|
||||||
|
";
|
||||||
|
static ref CODE: &'static str = "\
|
||||||
|
extern crate snap;
|
||||||
|
|
||||||
|
use std::io;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let stdin = io::stdin();
|
||||||
|
let stdout = io::stdout();
|
||||||
|
|
||||||
|
// Wrap the stdin reader in a Snappy reader.
|
||||||
|
let mut rdr = snap::Reader::new(stdin.lock());
|
||||||
|
let mut wtr = stdout.lock();
|
||||||
|
io::copy(&mut rdr, &mut wtr).expect(\"I/O operation failed\");
|
||||||
|
}
|
||||||
|
";
|
||||||
|
}
|
||||||
|
|
||||||
fn hay(s: &str) -> io::Cursor<Vec<u8>> {
|
fn hay(s: &str) -> io::Cursor<Vec<u8>> {
|
||||||
io::Cursor::new(s.to_string().into_bytes())
|
io::Cursor::new(s.to_string().into_bytes())
|
||||||
}
|
}
|
||||||
@ -603,16 +632,43 @@ mod tests {
|
|||||||
&Path::new("/baz.rs")
|
&Path::new("/baz.rs")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TestSearcher<'a> = Searcher<'a, io::Cursor<Vec<u8>>, Vec<u8>>;
|
||||||
|
|
||||||
|
fn search_smallcap<F: FnMut(TestSearcher) -> TestSearcher>(
|
||||||
|
pat: &str,
|
||||||
|
haystack: &str,
|
||||||
|
mut map: F,
|
||||||
|
) -> (u64, String) {
|
||||||
|
let mut inp = InputBuffer::with_capacity(1);
|
||||||
|
let mut pp = Printer::new(vec![]);
|
||||||
|
let grep = GrepBuilder::new(pat).build().unwrap();
|
||||||
|
let count = {
|
||||||
|
let searcher = Searcher::new(
|
||||||
|
&mut inp, &mut pp, &grep, test_path(), hay(haystack));
|
||||||
|
map(searcher).run().unwrap()
|
||||||
|
};
|
||||||
|
(count, String::from_utf8(pp.into_inner()).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn search<F: FnMut(TestSearcher) -> TestSearcher>(
|
||||||
|
pat: &str,
|
||||||
|
haystack: &str,
|
||||||
|
mut map: F,
|
||||||
|
) -> (u64, String) {
|
||||||
|
let mut inp = InputBuffer::with_capacity(4096);
|
||||||
|
let mut pp = Printer::new(vec![]);
|
||||||
|
let grep = GrepBuilder::new(pat).build().unwrap();
|
||||||
|
let count = {
|
||||||
|
let searcher = Searcher::new(
|
||||||
|
&mut inp, &mut pp, &grep, test_path(), hay(haystack));
|
||||||
|
map(searcher).run().unwrap()
|
||||||
|
};
|
||||||
|
(count, String::from_utf8(pp.into_inner()).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn previous_lines() {
|
fn previous_lines() {
|
||||||
let text = &b"\
|
let text = SHERLOCK.as_bytes();
|
||||||
For the Doctor Watsons of this world, as opposed to the Sherlock
|
|
||||||
Holmeses, success in the province of detective work must always
|
|
||||||
be, to a very large extent, the result of luck. Sherlock Holmes
|
|
||||||
can extract a clew from a wisp of straw or a flake of cigar ash;
|
|
||||||
but Doctor Watson has to have it taken out for him and dusted,
|
|
||||||
and exhibited clearly, with a label attached.\
|
|
||||||
"[..];
|
|
||||||
assert_eq!(366, text.len());
|
assert_eq!(366, text.len());
|
||||||
|
|
||||||
assert_eq!(0, start_of_previous_lines(text, 366, 100));
|
assert_eq!(0, start_of_previous_lines(text, 366, 100));
|
||||||
@ -712,24 +768,8 @@ and exhibited clearly, with a label attached.\
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn basic_search() {
|
fn basic_search() {
|
||||||
let text = hay("\
|
let (count, out) = search_smallcap("Sherlock", &*SHERLOCK, |s|s);
|
||||||
For the Doctor Watsons of this world, as opposed to the Sherlock
|
|
||||||
Holmeses, success in the province of detective work must always
|
|
||||||
be, to a very large extent, the result of luck. Sherlock Holmes
|
|
||||||
can extract a clew from a wisp of straw or a flake of cigar ash;
|
|
||||||
but Doctor Watson has to have it taken out for him and dusted,
|
|
||||||
and exhibited clearly, with a label attached.\
|
|
||||||
");
|
|
||||||
let mut inp = InputBuffer::with_capacity(1);
|
|
||||||
let mut pp = Printer::new(vec![]);
|
|
||||||
let grep = matcher("Sherlock");
|
|
||||||
let count = {
|
|
||||||
let searcher = Searcher::new(
|
|
||||||
&mut inp, &mut pp, &grep, test_path(), text);
|
|
||||||
searcher.run().unwrap()
|
|
||||||
};
|
|
||||||
assert_eq!(2, count);
|
assert_eq!(2, count);
|
||||||
let out = String::from_utf8(pp.into_inner()).unwrap();
|
|
||||||
assert_eq!(out, "\
|
assert_eq!(out, "\
|
||||||
/baz.rs:For the Doctor Watsons of this world, as opposed to the Sherlock
|
/baz.rs:For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||||
/baz.rs:be, to a very large extent, the result of luck. Sherlock Holmes
|
/baz.rs:be, to a very large extent, the result of luck. Sherlock Holmes
|
||||||
@ -738,24 +778,9 @@ and exhibited clearly, with a label attached.\
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn line_numbers() {
|
fn line_numbers() {
|
||||||
let text = hay("\
|
let (count, out) = search_smallcap(
|
||||||
For the Doctor Watsons of this world, as opposed to the Sherlock
|
"Sherlock", &*SHERLOCK, |s| s.line_number(true));
|
||||||
Holmeses, success in the province of detective work must always
|
|
||||||
be, to a very large extent, the result of luck. Sherlock Holmes
|
|
||||||
can extract a clew from a wisp of straw or a flake of cigar ash;
|
|
||||||
but Doctor Watson has to have it taken out for him and dusted,
|
|
||||||
and exhibited clearly, with a label attached.\
|
|
||||||
");
|
|
||||||
let mut inp = InputBuffer::with_capacity(1);
|
|
||||||
let mut pp = Printer::new(vec![]);
|
|
||||||
let grep = matcher("Sherlock");
|
|
||||||
let count = {
|
|
||||||
let searcher = Searcher::new(
|
|
||||||
&mut inp, &mut pp, &grep, test_path(), text);
|
|
||||||
searcher.line_number(true).run().unwrap()
|
|
||||||
};
|
|
||||||
assert_eq!(2, count);
|
assert_eq!(2, count);
|
||||||
let out = String::from_utf8(pp.into_inner()).unwrap();
|
|
||||||
assert_eq!(out, "\
|
assert_eq!(out, "\
|
||||||
/baz.rs:1:For the Doctor Watsons of this world, as opposed to the Sherlock
|
/baz.rs:1:For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||||
/baz.rs:3:be, to a very large extent, the result of luck. Sherlock Holmes
|
/baz.rs:3:be, to a very large extent, the result of luck. Sherlock Holmes
|
||||||
@ -764,47 +789,17 @@ and exhibited clearly, with a label attached.\
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn count() {
|
fn count() {
|
||||||
let text = hay("\
|
let (count, out) = search_smallcap(
|
||||||
For the Doctor Watsons of this world, as opposed to the Sherlock
|
"Sherlock", &*SHERLOCK, |s| s.count(true));
|
||||||
Holmeses, success in the province of detective work must always
|
|
||||||
be, to a very large extent, the result of luck. Sherlock Holmes
|
|
||||||
can extract a clew from a wisp of straw or a flake of cigar ash;
|
|
||||||
but Doctor Watson has to have it taken out for him and dusted,
|
|
||||||
and exhibited clearly, with a label attached.\
|
|
||||||
");
|
|
||||||
let mut inp = InputBuffer::with_capacity(1);
|
|
||||||
let mut pp = Printer::new(vec![]);
|
|
||||||
let grep = matcher("Sherlock");
|
|
||||||
let count = {
|
|
||||||
let searcher = Searcher::new(
|
|
||||||
&mut inp, &mut pp, &grep, test_path(), text);
|
|
||||||
searcher.count(true).run().unwrap()
|
|
||||||
};
|
|
||||||
assert_eq!(2, count);
|
assert_eq!(2, count);
|
||||||
let out = String::from_utf8(pp.into_inner()).unwrap();
|
|
||||||
assert_eq!(out, "/baz.rs:2\n");
|
assert_eq!(out, "/baz.rs:2\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn invert_match() {
|
fn invert_match() {
|
||||||
let text = hay("\
|
let (count, out) = search_smallcap(
|
||||||
For the Doctor Watsons of this world, as opposed to the Sherlock
|
"Sherlock", &*SHERLOCK, |s| s.invert_match(true));
|
||||||
Holmeses, success in the province of detective work must always
|
|
||||||
be, to a very large extent, the result of luck. Sherlock Holmes
|
|
||||||
can extract a clew from a wisp of straw or a flake of cigar ash;
|
|
||||||
but Doctor Watson has to have it taken out for him and dusted,
|
|
||||||
and exhibited clearly, with a label attached.\
|
|
||||||
");
|
|
||||||
let mut inp = InputBuffer::with_capacity(1);
|
|
||||||
let mut pp = Printer::new(vec![]);
|
|
||||||
let grep = matcher("Sherlock");
|
|
||||||
let count = {
|
|
||||||
let searcher = Searcher::new(
|
|
||||||
&mut inp, &mut pp, &grep, test_path(), text);
|
|
||||||
searcher.invert_match(true).run().unwrap()
|
|
||||||
};
|
|
||||||
assert_eq!(4, count);
|
assert_eq!(4, count);
|
||||||
let out = String::from_utf8(pp.into_inner()).unwrap();
|
|
||||||
assert_eq!(out, "\
|
assert_eq!(out, "\
|
||||||
/baz.rs:Holmeses, success in the province of detective work must always
|
/baz.rs:Holmeses, success in the province of detective work must always
|
||||||
/baz.rs:can extract a clew from a wisp of straw or a flake of cigar ash;
|
/baz.rs:can extract a clew from a wisp of straw or a flake of cigar ash;
|
||||||
@ -815,24 +810,10 @@ and exhibited clearly, with a label attached.\
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn invert_match_line_numbers() {
|
fn invert_match_line_numbers() {
|
||||||
let text = hay("\
|
let (count, out) = search_smallcap("Sherlock", &*SHERLOCK, |s| {
|
||||||
For the Doctor Watsons of this world, as opposed to the Sherlock
|
s.invert_match(true).line_number(true)
|
||||||
Holmeses, success in the province of detective work must always
|
});
|
||||||
be, to a very large extent, the result of luck. Sherlock Holmes
|
|
||||||
can extract a clew from a wisp of straw or a flake of cigar ash;
|
|
||||||
but Doctor Watson has to have it taken out for him and dusted,
|
|
||||||
and exhibited clearly, with a label attached.\
|
|
||||||
");
|
|
||||||
let mut inp = InputBuffer::with_capacity(1);
|
|
||||||
let mut pp = Printer::new(vec![]);
|
|
||||||
let grep = matcher("Sherlock");
|
|
||||||
let count = {
|
|
||||||
let searcher = Searcher::new(
|
|
||||||
&mut inp, &mut pp, &grep, test_path(), text);
|
|
||||||
searcher.invert_match(true).line_number(true).run().unwrap()
|
|
||||||
};
|
|
||||||
assert_eq!(4, count);
|
assert_eq!(4, count);
|
||||||
let out = String::from_utf8(pp.into_inner()).unwrap();
|
|
||||||
assert_eq!(out, "\
|
assert_eq!(out, "\
|
||||||
/baz.rs:2:Holmeses, success in the province of detective work must always
|
/baz.rs:2:Holmeses, success in the province of detective work must always
|
||||||
/baz.rs:4:can extract a clew from a wisp of straw or a flake of cigar ash;
|
/baz.rs:4:can extract a clew from a wisp of straw or a flake of cigar ash;
|
||||||
@ -843,95 +824,91 @@ and exhibited clearly, with a label attached.\
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn invert_match_count() {
|
fn invert_match_count() {
|
||||||
let text = hay("\
|
let (count, out) = search_smallcap("Sherlock", &*SHERLOCK, |s| {
|
||||||
For the Doctor Watsons of this world, as opposed to the Sherlock
|
s.invert_match(true).count(true)
|
||||||
Holmeses, success in the province of detective work must always
|
});
|
||||||
be, to a very large extent, the result of luck. Sherlock Holmes
|
|
||||||
can extract a clew from a wisp of straw or a flake of cigar ash;
|
|
||||||
but Doctor Watson has to have it taken out for him and dusted,
|
|
||||||
and exhibited clearly, with a label attached.\
|
|
||||||
");
|
|
||||||
let mut inp = InputBuffer::with_capacity(1);
|
|
||||||
let mut pp = Printer::new(vec![]);
|
|
||||||
let grep = matcher("Sherlock");
|
|
||||||
let count = {
|
|
||||||
let searcher = Searcher::new(
|
|
||||||
&mut inp, &mut pp, &grep, test_path(), text);
|
|
||||||
searcher.invert_match(true).count(true).run().unwrap()
|
|
||||||
};
|
|
||||||
assert_eq!(4, count);
|
assert_eq!(4, count);
|
||||||
let out = String::from_utf8(pp.into_inner()).unwrap();
|
|
||||||
assert_eq!(out, "/baz.rs:4\n");
|
assert_eq!(out, "/baz.rs:4\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! before_context {
|
#[test]
|
||||||
($name:ident, $query:expr, $num:expr, $expect:expr) => {
|
fn before_context_one1() {
|
||||||
before_context!($name, $query, $num, $expect, false);
|
let (count, out) = search_smallcap("Sherlock", &*SHERLOCK, |s| {
|
||||||
};
|
s.line_number(true).before_context(1)
|
||||||
($name:ident, $query:expr, $num:expr, $expect:expr, $invert:expr) => {
|
});
|
||||||
#[test]
|
assert_eq!(2, count);
|
||||||
fn $name() {
|
assert_eq!(out, "\
|
||||||
let text = hay("\
|
|
||||||
For the Doctor Watsons of this world, as opposed to the Sherlock
|
|
||||||
Holmeses, success in the province of detective work must always
|
|
||||||
be, to a very large extent, the result of luck. Sherlock Holmes
|
|
||||||
can extract a clew from a wisp of straw or a flake of cigar ash;
|
|
||||||
but Doctor Watson has to have it taken out for him and dusted,
|
|
||||||
and exhibited clearly, with a label attached.\
|
|
||||||
");
|
|
||||||
let mut inp = InputBuffer::with_capacity(4096);
|
|
||||||
let mut pp = Printer::new(vec![]);
|
|
||||||
let grep = matcher($query);
|
|
||||||
let count = {
|
|
||||||
let mut searcher = Searcher::new(
|
|
||||||
&mut inp, &mut pp, &grep, test_path(), text);
|
|
||||||
searcher = searcher.line_number(true);
|
|
||||||
searcher = searcher.before_context($num);
|
|
||||||
searcher = searcher.invert_match($invert);
|
|
||||||
searcher.run().unwrap()
|
|
||||||
};
|
|
||||||
let out = String::from_utf8(pp.into_inner()).unwrap();
|
|
||||||
assert_eq!(out, $expect);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
before_context!(before_context_one, "Sherlock", 1, "\
|
|
||||||
/baz.rs:1:For the Doctor Watsons of this world, as opposed to the Sherlock
|
/baz.rs:1:For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||||
/baz.rs-2-Holmeses, success in the province of detective work must always
|
/baz.rs-2-Holmeses, success in the province of detective work must always
|
||||||
/baz.rs:3:be, to a very large extent, the result of luck. Sherlock Holmes
|
/baz.rs:3:be, to a very large extent, the result of luck. Sherlock Holmes
|
||||||
");
|
");
|
||||||
|
}
|
||||||
|
|
||||||
before_context!(before_context_invert_one1, "Sherlock", 1, "\
|
#[test]
|
||||||
|
fn before_context_invert_one1() {
|
||||||
|
let (count, out) = search_smallcap("Sherlock", &*SHERLOCK, |s| {
|
||||||
|
s.line_number(true).before_context(1).invert_match(true)
|
||||||
|
});
|
||||||
|
assert_eq!(4, count);
|
||||||
|
assert_eq!(out, "\
|
||||||
/baz.rs-1-For the Doctor Watsons of this world, as opposed to the Sherlock
|
/baz.rs-1-For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||||
/baz.rs:2:Holmeses, success in the province of detective work must always
|
/baz.rs:2:Holmeses, success in the province of detective work must always
|
||||||
/baz.rs-3-be, to a very large extent, the result of luck. Sherlock Holmes
|
/baz.rs-3-be, to a very large extent, the result of luck. Sherlock Holmes
|
||||||
/baz.rs:4:can extract a clew from a wisp of straw or a flake of cigar ash;
|
/baz.rs:4:can extract a clew from a wisp of straw or a flake of cigar ash;
|
||||||
/baz.rs:5:but Doctor Watson has to have it taken out for him and dusted,
|
/baz.rs:5:but Doctor Watson has to have it taken out for him and dusted,
|
||||||
/baz.rs:6:and exhibited clearly, with a label attached.
|
/baz.rs:6:and exhibited clearly, with a label attached.
|
||||||
", true);
|
");
|
||||||
|
}
|
||||||
|
|
||||||
before_context!(before_context_invert_one2, " a ", 1, "\
|
#[test]
|
||||||
|
fn before_context_invert_one2() {
|
||||||
|
let (count, out) = search_smallcap(" a ", &*SHERLOCK, |s| {
|
||||||
|
s.line_number(true).before_context(1).invert_match(true)
|
||||||
|
});
|
||||||
|
assert_eq!(3, count);
|
||||||
|
assert_eq!(out, "\
|
||||||
/baz.rs:1:For the Doctor Watsons of this world, as opposed to the Sherlock
|
/baz.rs:1:For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||||
/baz.rs:2:Holmeses, success in the province of detective work must always
|
/baz.rs:2:Holmeses, success in the province of detective work must always
|
||||||
--
|
--
|
||||||
/baz.rs-4-can extract a clew from a wisp of straw or a flake of cigar ash;
|
/baz.rs-4-can extract a clew from a wisp of straw or a flake of cigar ash;
|
||||||
/baz.rs:5:but Doctor Watson has to have it taken out for him and dusted,
|
/baz.rs:5:but Doctor Watson has to have it taken out for him and dusted,
|
||||||
", true);
|
");
|
||||||
|
}
|
||||||
|
|
||||||
before_context!(before_context_two1, "Sherlock", 2, "\
|
#[test]
|
||||||
|
fn before_context_two1() {
|
||||||
|
let (count, out) = search_smallcap("Sherlock", &*SHERLOCK, |s| {
|
||||||
|
s.line_number(true).before_context(2)
|
||||||
|
});
|
||||||
|
assert_eq!(2, count);
|
||||||
|
assert_eq!(out, "\
|
||||||
/baz.rs:1:For the Doctor Watsons of this world, as opposed to the Sherlock
|
/baz.rs:1:For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||||
/baz.rs-2-Holmeses, success in the province of detective work must always
|
/baz.rs-2-Holmeses, success in the province of detective work must always
|
||||||
/baz.rs:3:be, to a very large extent, the result of luck. Sherlock Holmes
|
/baz.rs:3:be, to a very large extent, the result of luck. Sherlock Holmes
|
||||||
");
|
");
|
||||||
|
}
|
||||||
|
|
||||||
before_context!(before_context_two2, "dusted", 2, "\
|
#[test]
|
||||||
|
fn before_context_two2() {
|
||||||
|
let (count, out) = search_smallcap("dusted", &*SHERLOCK, |s| {
|
||||||
|
s.line_number(true).before_context(2)
|
||||||
|
});
|
||||||
|
assert_eq!(1, count);
|
||||||
|
assert_eq!(out, "\
|
||||||
/baz.rs-3-be, to a very large extent, the result of luck. Sherlock Holmes
|
/baz.rs-3-be, to a very large extent, the result of luck. Sherlock Holmes
|
||||||
/baz.rs-4-can extract a clew from a wisp of straw or a flake of cigar ash;
|
/baz.rs-4-can extract a clew from a wisp of straw or a flake of cigar ash;
|
||||||
/baz.rs:5:but Doctor Watson has to have it taken out for him and dusted,
|
/baz.rs:5:but Doctor Watson has to have it taken out for him and dusted,
|
||||||
");
|
");
|
||||||
|
}
|
||||||
|
|
||||||
before_context!(before_context_two3, "success|attached", 2, "\
|
#[test]
|
||||||
|
fn before_context_two3() {
|
||||||
|
let (count, out) = search_smallcap(
|
||||||
|
"success|attached", &*SHERLOCK, |s| {
|
||||||
|
s.line_number(true).before_context(2)
|
||||||
|
});
|
||||||
|
assert_eq!(2, count);
|
||||||
|
assert_eq!(out, "\
|
||||||
/baz.rs-1-For the Doctor Watsons of this world, as opposed to the Sherlock
|
/baz.rs-1-For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||||
/baz.rs:2:Holmeses, success in the province of detective work must always
|
/baz.rs:2:Holmeses, success in the province of detective work must always
|
||||||
--
|
--
|
||||||
@ -939,91 +916,150 @@ and exhibited clearly, with a label attached.\
|
|||||||
/baz.rs-5-but Doctor Watson has to have it taken out for him and dusted,
|
/baz.rs-5-but Doctor Watson has to have it taken out for him and dusted,
|
||||||
/baz.rs:6:and exhibited clearly, with a label attached.
|
/baz.rs:6:and exhibited clearly, with a label attached.
|
||||||
");
|
");
|
||||||
|
}
|
||||||
|
|
||||||
before_context!(before_context_three, "Sherlock", 3, "\
|
#[test]
|
||||||
|
fn before_context_two4() {
|
||||||
|
let (count, out) = search("stdin", &*CODE, |s| {
|
||||||
|
s.line_number(true).before_context(2)
|
||||||
|
});
|
||||||
|
assert_eq!(3, count);
|
||||||
|
assert_eq!(out, "\
|
||||||
|
/baz.rs-4-
|
||||||
|
/baz.rs-5-fn main() {
|
||||||
|
/baz.rs:6: let stdin = io::stdin();
|
||||||
|
/baz.rs-7- let stdout = io::stdout();
|
||||||
|
/baz.rs-8-
|
||||||
|
/baz.rs:9: // Wrap the stdin reader in a Snappy reader.
|
||||||
|
/baz.rs:10: let mut rdr = snap::Reader::new(stdin.lock());
|
||||||
|
");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn before_context_two5() {
|
||||||
|
let (count, out) = search("stdout", &*CODE, |s| {
|
||||||
|
s.line_number(true).before_context(2)
|
||||||
|
});
|
||||||
|
assert_eq!(2, count);
|
||||||
|
assert_eq!(out, "\
|
||||||
|
/baz.rs-5-fn main() {
|
||||||
|
/baz.rs-6- let stdin = io::stdin();
|
||||||
|
/baz.rs:7: let stdout = io::stdout();
|
||||||
|
--
|
||||||
|
/baz.rs-9- // Wrap the stdin reader in a Snappy reader.
|
||||||
|
/baz.rs-10- let mut rdr = snap::Reader::new(stdin.lock());
|
||||||
|
/baz.rs:11: let mut wtr = stdout.lock();
|
||||||
|
");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn before_context_three1() {
|
||||||
|
let (count, out) = search_smallcap("Sherlock", &*SHERLOCK, |s| {
|
||||||
|
s.line_number(true).before_context(3)
|
||||||
|
});
|
||||||
|
assert_eq!(2, count);
|
||||||
|
assert_eq!(out, "\
|
||||||
/baz.rs:1:For the Doctor Watsons of this world, as opposed to the Sherlock
|
/baz.rs:1:For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||||
/baz.rs-2-Holmeses, success in the province of detective work must always
|
/baz.rs-2-Holmeses, success in the province of detective work must always
|
||||||
/baz.rs:3:be, to a very large extent, the result of luck. Sherlock Holmes
|
/baz.rs:3:be, to a very large extent, the result of luck. Sherlock Holmes
|
||||||
");
|
");
|
||||||
|
|
||||||
macro_rules! after_context {
|
|
||||||
($name:ident, $query:expr, $num:expr, $expect:expr) => {
|
|
||||||
after_context!($name, $query, $num, $expect, false);
|
|
||||||
};
|
|
||||||
($name:ident, $query:expr, $num:expr, $expect:expr, $invert:expr) => {
|
|
||||||
#[test]
|
|
||||||
fn $name() {
|
|
||||||
let text = hay("\
|
|
||||||
For the Doctor Watsons of this world, as opposed to the Sherlock
|
|
||||||
Holmeses, success in the province of detective work must always
|
|
||||||
be, to a very large extent, the result of luck. Sherlock Holmes
|
|
||||||
can extract a clew from a wisp of straw or a flake of cigar ash;
|
|
||||||
but Doctor Watson has to have it taken out for him and dusted,
|
|
||||||
and exhibited clearly, with a label attached.\
|
|
||||||
");
|
|
||||||
let mut inp = InputBuffer::with_capacity(4096);
|
|
||||||
let mut pp = Printer::new(vec![]);
|
|
||||||
let grep = matcher($query);
|
|
||||||
let count = {
|
|
||||||
let mut searcher = Searcher::new(
|
|
||||||
&mut inp, &mut pp, &grep, test_path(), text);
|
|
||||||
searcher = searcher.line_number(true);
|
|
||||||
searcher = searcher.after_context($num);
|
|
||||||
searcher = searcher.invert_match($invert);
|
|
||||||
searcher.run().unwrap()
|
|
||||||
};
|
|
||||||
let out = String::from_utf8(pp.into_inner()).unwrap();
|
|
||||||
assert_eq!(out, $expect);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
after_context!(after_context_one, "Sherlock", 1, "\
|
#[test]
|
||||||
|
fn after_context_one1() {
|
||||||
|
let (count, out) = search_smallcap("Sherlock", &*SHERLOCK, |s| {
|
||||||
|
s.line_number(true).after_context(1)
|
||||||
|
});
|
||||||
|
assert_eq!(2, count);
|
||||||
|
assert_eq!(out, "\
|
||||||
/baz.rs:1:For the Doctor Watsons of this world, as opposed to the Sherlock
|
/baz.rs:1:For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||||
/baz.rs-2-Holmeses, success in the province of detective work must always
|
/baz.rs-2-Holmeses, success in the province of detective work must always
|
||||||
/baz.rs:3:be, to a very large extent, the result of luck. Sherlock Holmes
|
/baz.rs:3:be, to a very large extent, the result of luck. Sherlock Holmes
|
||||||
/baz.rs-4-can extract a clew from a wisp of straw or a flake of cigar ash;
|
/baz.rs-4-can extract a clew from a wisp of straw or a flake of cigar ash;
|
||||||
");
|
");
|
||||||
|
}
|
||||||
|
|
||||||
after_context!(after_context_invert_one1, "Sherlock", 1, "\
|
#[test]
|
||||||
|
fn after_context_invert_one1() {
|
||||||
|
let (count, out) = search_smallcap("Sherlock", &*SHERLOCK, |s| {
|
||||||
|
s.line_number(true).after_context(1).invert_match(true)
|
||||||
|
});
|
||||||
|
assert_eq!(4, count);
|
||||||
|
assert_eq!(out, "\
|
||||||
/baz.rs:2:Holmeses, success in the province of detective work must always
|
/baz.rs:2:Holmeses, success in the province of detective work must always
|
||||||
/baz.rs-3-be, to a very large extent, the result of luck. Sherlock Holmes
|
/baz.rs-3-be, to a very large extent, the result of luck. Sherlock Holmes
|
||||||
/baz.rs:4:can extract a clew from a wisp of straw or a flake of cigar ash;
|
/baz.rs:4:can extract a clew from a wisp of straw or a flake of cigar ash;
|
||||||
/baz.rs:5:but Doctor Watson has to have it taken out for him and dusted,
|
/baz.rs:5:but Doctor Watson has to have it taken out for him and dusted,
|
||||||
/baz.rs:6:and exhibited clearly, with a label attached.
|
/baz.rs:6:and exhibited clearly, with a label attached.
|
||||||
", true);
|
");
|
||||||
|
}
|
||||||
|
|
||||||
after_context!(after_context_invert_one2, " a ", 1, "\
|
#[test]
|
||||||
|
fn after_context_invert_one2() {
|
||||||
|
let (count, out) = search_smallcap(" a ", &*SHERLOCK, |s| {
|
||||||
|
s.line_number(true).after_context(1).invert_match(true)
|
||||||
|
});
|
||||||
|
assert_eq!(3, count);
|
||||||
|
assert_eq!(out, "\
|
||||||
/baz.rs:1:For the Doctor Watsons of this world, as opposed to the Sherlock
|
/baz.rs:1:For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||||
/baz.rs:2:Holmeses, success in the province of detective work must always
|
/baz.rs:2:Holmeses, success in the province of detective work must always
|
||||||
/baz.rs-3-be, to a very large extent, the result of luck. Sherlock Holmes
|
/baz.rs-3-be, to a very large extent, the result of luck. Sherlock Holmes
|
||||||
--
|
--
|
||||||
/baz.rs:5:but Doctor Watson has to have it taken out for him and dusted,
|
/baz.rs:5:but Doctor Watson has to have it taken out for him and dusted,
|
||||||
/baz.rs-6-and exhibited clearly, with a label attached.
|
/baz.rs-6-and exhibited clearly, with a label attached.
|
||||||
", true);
|
");
|
||||||
|
}
|
||||||
|
|
||||||
after_context!(after_context_two1, "Sherlock", 2, "\
|
#[test]
|
||||||
|
fn after_context_two1() {
|
||||||
|
let (count, out) = search_smallcap("Sherlock", &*SHERLOCK, |s| {
|
||||||
|
s.line_number(true).after_context(2)
|
||||||
|
});
|
||||||
|
assert_eq!(2, count);
|
||||||
|
assert_eq!(out, "\
|
||||||
/baz.rs:1:For the Doctor Watsons of this world, as opposed to the Sherlock
|
/baz.rs:1:For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||||
/baz.rs-2-Holmeses, success in the province of detective work must always
|
/baz.rs-2-Holmeses, success in the province of detective work must always
|
||||||
/baz.rs:3:be, to a very large extent, the result of luck. Sherlock Holmes
|
/baz.rs:3:be, to a very large extent, the result of luck. Sherlock Holmes
|
||||||
/baz.rs-4-can extract a clew from a wisp of straw or a flake of cigar ash;
|
/baz.rs-4-can extract a clew from a wisp of straw or a flake of cigar ash;
|
||||||
/baz.rs-5-but Doctor Watson has to have it taken out for him and dusted,
|
/baz.rs-5-but Doctor Watson has to have it taken out for him and dusted,
|
||||||
");
|
");
|
||||||
|
}
|
||||||
|
|
||||||
after_context!(after_context_two2, "dusted", 2, "\
|
#[test]
|
||||||
|
fn after_context_two2() {
|
||||||
|
let (count, out) = search_smallcap("dusted", &*SHERLOCK, |s| {
|
||||||
|
s.line_number(true).after_context(2)
|
||||||
|
});
|
||||||
|
assert_eq!(1, count);
|
||||||
|
assert_eq!(out, "\
|
||||||
/baz.rs:5:but Doctor Watson has to have it taken out for him and dusted,
|
/baz.rs:5:but Doctor Watson has to have it taken out for him and dusted,
|
||||||
/baz.rs-6-and exhibited clearly, with a label attached.
|
/baz.rs-6-and exhibited clearly, with a label attached.
|
||||||
");
|
");
|
||||||
|
}
|
||||||
|
|
||||||
after_context!(after_context_two3, "success|attached", 2, "\
|
#[test]
|
||||||
|
fn after_context_two3() {
|
||||||
|
let (count, out) = search_smallcap(
|
||||||
|
"success|attached", &*SHERLOCK, |s| {
|
||||||
|
s.line_number(true).after_context(2)
|
||||||
|
});
|
||||||
|
assert_eq!(2, count);
|
||||||
|
assert_eq!(out, "\
|
||||||
/baz.rs:2:Holmeses, success in the province of detective work must always
|
/baz.rs:2:Holmeses, success in the province of detective work must always
|
||||||
/baz.rs-3-be, to a very large extent, the result of luck. Sherlock Holmes
|
/baz.rs-3-be, to a very large extent, the result of luck. Sherlock Holmes
|
||||||
/baz.rs-4-can extract a clew from a wisp of straw or a flake of cigar ash;
|
/baz.rs-4-can extract a clew from a wisp of straw or a flake of cigar ash;
|
||||||
--
|
--
|
||||||
/baz.rs:6:and exhibited clearly, with a label attached.
|
/baz.rs:6:and exhibited clearly, with a label attached.
|
||||||
");
|
");
|
||||||
|
}
|
||||||
|
|
||||||
after_context!(after_context_three, "Sherlock", 3, "\
|
#[test]
|
||||||
|
fn after_context_three1() {
|
||||||
|
let (count, out) = search_smallcap("Sherlock", &*SHERLOCK, |s| {
|
||||||
|
s.line_number(true).after_context(3)
|
||||||
|
});
|
||||||
|
assert_eq!(2, count);
|
||||||
|
assert_eq!(out, "\
|
||||||
/baz.rs:1:For the Doctor Watsons of this world, as opposed to the Sherlock
|
/baz.rs:1:For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||||
/baz.rs-2-Holmeses, success in the province of detective work must always
|
/baz.rs-2-Holmeses, success in the province of detective work must always
|
||||||
/baz.rs:3:be, to a very large extent, the result of luck. Sherlock Holmes
|
/baz.rs:3:be, to a very large extent, the result of luck. Sherlock Holmes
|
||||||
@ -1031,4 +1067,26 @@ and exhibited clearly, with a label attached.\
|
|||||||
/baz.rs-5-but Doctor Watson has to have it taken out for him and dusted,
|
/baz.rs-5-but Doctor Watson has to have it taken out for him and dusted,
|
||||||
/baz.rs-6-and exhibited clearly, with a label attached.
|
/baz.rs-6-and exhibited clearly, with a label attached.
|
||||||
");
|
");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn before_after_context_two1() {
|
||||||
|
let (count, out) = search(
|
||||||
|
r"fn main|let mut rdr", &*CODE, |s| {
|
||||||
|
s.line_number(true).after_context(2).before_context(2)
|
||||||
|
});
|
||||||
|
assert_eq!(2, count);
|
||||||
|
assert_eq!(out, "\
|
||||||
|
/baz.rs-3-use std::io;
|
||||||
|
/baz.rs-4-
|
||||||
|
/baz.rs:5:fn main() {
|
||||||
|
/baz.rs-6- let stdin = io::stdin();
|
||||||
|
/baz.rs-7- let stdout = io::stdout();
|
||||||
|
/baz.rs-8-
|
||||||
|
/baz.rs-9- // Wrap the stdin reader in a Snappy reader.
|
||||||
|
/baz.rs:10: let mut rdr = snap::Reader::new(stdin.lock());
|
||||||
|
/baz.rs-11- let mut wtr = stdout.lock();
|
||||||
|
/baz.rs-12- io::copy(&mut rdr, &mut wtr).expect(\"I/O operation failed\");
|
||||||
|
");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user