PageRenderTime 117ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/feature.rs

https://github.com/BurntSushi/ripgrep
Rust | 843 lines | 612 code | 133 blank | 98 comment | 4 complexity | 74e6d537d254e41d238a37bbf3972642 MD5 | raw file
Possible License(s): MIT, Unlicense
  1. use crate::hay::{SHERLOCK, SHERLOCK_CRLF};
  2. use crate::util::{sort_lines, Dir, TestCommand};
  3. // See: https://github.com/BurntSushi/ripgrep/issues/1
  4. rgtest!(f1_sjis, |dir: Dir, mut cmd: TestCommand| {
  5. dir.create_bytes(
  6. "foo",
  7. b"\x84Y\x84u\x84\x82\x84|\x84\x80\x84{ \x84V\x84\x80\x84|\x84}\x84\x83"
  8. );
  9. cmd.arg("-Esjis").arg("Шерлок Холмс");
  10. eqnice!("foo:Шерлок Холмс\n", cmd.stdout());
  11. });
  12. // See: https://github.com/BurntSushi/ripgrep/issues/1
  13. rgtest!(f1_utf16_auto, |dir: Dir, mut cmd: TestCommand| {
  14. dir.create_bytes(
  15. "foo",
  16. b"\xff\xfe(\x045\x04@\x04;\x04>\x04:\x04 \x00%\x04>\x04;\x04<\x04A\x04"
  17. );
  18. cmd.arg("Шерлок Холмс");
  19. eqnice!("foo:Шерлок Холмс\n", cmd.stdout());
  20. });
  21. // See: https://github.com/BurntSushi/ripgrep/issues/1
  22. rgtest!(f1_utf16_explicit, |dir: Dir, mut cmd: TestCommand| {
  23. dir.create_bytes(
  24. "foo",
  25. b"\xff\xfe(\x045\x04@\x04;\x04>\x04:\x04 \x00%\x04>\x04;\x04<\x04A\x04"
  26. );
  27. cmd.arg("-Eutf-16le").arg("Шерлок Холмс");
  28. eqnice!("foo:Шерлок Холмс\n", cmd.stdout());
  29. });
  30. // See: https://github.com/BurntSushi/ripgrep/issues/1
  31. rgtest!(f1_eucjp, |dir: Dir, mut cmd: TestCommand| {
  32. dir.create_bytes(
  33. "foo",
  34. b"\xa7\xba\xa7\xd6\xa7\xe2\xa7\xdd\xa7\xe0\xa7\xdc \xa7\xb7\xa7\xe0\xa7\xdd\xa7\xde\xa7\xe3"
  35. );
  36. cmd.arg("-Eeuc-jp").arg("Шерлок Холмс");
  37. eqnice!("foo:Шерлок Холмс\n", cmd.stdout());
  38. });
  39. // See: https://github.com/BurntSushi/ripgrep/issues/1
  40. rgtest!(f1_unknown_encoding, |_: Dir, mut cmd: TestCommand| {
  41. cmd.arg("-Efoobar").assert_non_empty_stderr();
  42. });
  43. // See: https://github.com/BurntSushi/ripgrep/issues/1
  44. rgtest!(f1_replacement_encoding, |_: Dir, mut cmd: TestCommand| {
  45. cmd.arg("-Ecsiso2022kr").assert_non_empty_stderr();
  46. });
  47. // See: https://github.com/BurntSushi/ripgrep/issues/7
  48. rgtest!(f7, |dir: Dir, mut cmd: TestCommand| {
  49. dir.create("sherlock", SHERLOCK);
  50. dir.create("pat", "Sherlock\nHolmes");
  51. let expected = "\
  52. For the Doctor Watsons of this world, as opposed to the Sherlock
  53. Holmeses, success in the province of detective work must always
  54. be, to a very large extent, the result of luck. Sherlock Holmes
  55. ";
  56. eqnice!(expected, cmd.arg("-fpat").arg("sherlock").stdout());
  57. });
  58. // See: https://github.com/BurntSushi/ripgrep/issues/7
  59. rgtest!(f7_stdin, |dir: Dir, mut cmd: TestCommand| {
  60. dir.create("sherlock", SHERLOCK);
  61. let expected = "\
  62. sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
  63. sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
  64. ";
  65. eqnice!(expected, cmd.arg("-f-").pipe(b"Sherlock"));
  66. });
  67. // See: https://github.com/BurntSushi/ripgrep/issues/20
  68. rgtest!(f20_no_filename, |dir: Dir, mut cmd: TestCommand| {
  69. dir.create("sherlock", SHERLOCK);
  70. cmd.arg("--no-filename");
  71. let expected = "\
  72. For the Doctor Watsons of this world, as opposed to the Sherlock
  73. be, to a very large extent, the result of luck. Sherlock Holmes
  74. ";
  75. eqnice!(expected, cmd.arg("--no-filename").arg("Sherlock").stdout());
  76. });
  77. // See: https://github.com/BurntSushi/ripgrep/issues/34
  78. rgtest!(f34_only_matching, |dir: Dir, mut cmd: TestCommand| {
  79. dir.create("sherlock", SHERLOCK);
  80. let expected = "\
  81. sherlock:Sherlock
  82. sherlock:Sherlock
  83. ";
  84. eqnice!(expected, cmd.arg("-o").arg("Sherlock").stdout());
  85. });
  86. // See: https://github.com/BurntSushi/ripgrep/issues/34
  87. rgtest!(f34_only_matching_line_column, |dir: Dir, mut cmd: TestCommand| {
  88. dir.create("sherlock", SHERLOCK);
  89. let expected = "\
  90. sherlock:1:57:Sherlock
  91. sherlock:3:49:Sherlock
  92. ";
  93. cmd.arg("-o").arg("--column").arg("-n").arg("Sherlock");
  94. eqnice!(expected, cmd.stdout());
  95. });
  96. // See: https://github.com/BurntSushi/ripgrep/issues/45
  97. rgtest!(f45_relative_cwd, |dir: Dir, mut cmd: TestCommand| {
  98. dir.create(".not-an-ignore", "foo\n/bar");
  99. dir.create_dir("bar");
  100. dir.create_dir("baz/bar");
  101. dir.create_dir("baz/baz/bar");
  102. dir.create("bar/test", "test");
  103. dir.create("baz/bar/test", "test");
  104. dir.create("baz/baz/bar/test", "test");
  105. dir.create("baz/foo", "test");
  106. dir.create("baz/test", "test");
  107. dir.create("foo", "test");
  108. dir.create("test", "test");
  109. cmd.arg("-l").arg("test");
  110. // First, get a baseline without applying ignore rules.
  111. let expected = "
  112. bar/test
  113. baz/bar/test
  114. baz/baz/bar/test
  115. baz/foo
  116. baz/test
  117. foo
  118. test
  119. ";
  120. eqnice!(sort_lines(expected), sort_lines(&cmd.stdout()));
  121. // Now try again with the ignore file activated.
  122. cmd.arg("--ignore-file").arg(".not-an-ignore");
  123. let expected = "
  124. baz/bar/test
  125. baz/baz/bar/test
  126. baz/test
  127. test
  128. ";
  129. eqnice!(sort_lines(expected), sort_lines(&cmd.stdout()));
  130. // Now do it again, but inside the baz directory. Since the ignore file
  131. // is interpreted relative to the CWD, this will cause the /bar anchored
  132. // pattern to filter out baz/bar, which is a subtle difference between true
  133. // parent ignore files and manually specified ignore files.
  134. let mut cmd = dir.command();
  135. cmd.args(&["--ignore-file", "../.not-an-ignore", "-l", "test"]);
  136. cmd.current_dir(dir.path().join("baz"));
  137. let expected = "
  138. baz/bar/test
  139. test
  140. ";
  141. eqnice!(sort_lines(expected), sort_lines(&cmd.stdout()));
  142. });
  143. // See: https://github.com/BurntSushi/ripgrep/issues/45
  144. rgtest!(f45_precedence_with_others, |dir: Dir, mut cmd: TestCommand| {
  145. dir.create(".not-an-ignore", "*.log");
  146. dir.create(".ignore", "!imp.log");
  147. dir.create("imp.log", "test");
  148. dir.create("wat.log", "test");
  149. cmd.arg("--ignore-file").arg(".not-an-ignore").arg("test");
  150. eqnice!("imp.log:test\n", cmd.stdout());
  151. });
  152. // See: https://github.com/BurntSushi/ripgrep/issues/45
  153. rgtest!(f45_precedence_internal, |dir: Dir, mut cmd: TestCommand| {
  154. dir.create(".not-an-ignore1", "*.log");
  155. dir.create(".not-an-ignore2", "!imp.log");
  156. dir.create("imp.log", "test");
  157. dir.create("wat.log", "test");
  158. cmd.args(&[
  159. "--ignore-file",
  160. ".not-an-ignore1",
  161. "--ignore-file",
  162. ".not-an-ignore2",
  163. "test",
  164. ]);
  165. eqnice!("imp.log:test\n", cmd.stdout());
  166. });
  167. // See: https://github.com/BurntSushi/ripgrep/issues/68
  168. rgtest!(f68_no_ignore_vcs, |dir: Dir, mut cmd: TestCommand| {
  169. dir.create_dir(".git");
  170. dir.create(".gitignore", "foo");
  171. dir.create(".ignore", "bar");
  172. dir.create("foo", "test");
  173. dir.create("bar", "test");
  174. eqnice!("foo:test\n", cmd.arg("--no-ignore-vcs").arg("test").stdout());
  175. });
  176. // See: https://github.com/BurntSushi/ripgrep/issues/70
  177. rgtest!(f70_smart_case, |dir: Dir, mut cmd: TestCommand| {
  178. dir.create("sherlock", SHERLOCK);
  179. let expected = "\
  180. sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
  181. sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
  182. ";
  183. eqnice!(expected, cmd.arg("-S").arg("sherlock").stdout());
  184. });
  185. // See: https://github.com/BurntSushi/ripgrep/issues/89
  186. rgtest!(f89_files_with_matches, |dir: Dir, mut cmd: TestCommand| {
  187. dir.create("sherlock", SHERLOCK);
  188. cmd.arg("--null").arg("--files-with-matches").arg("Sherlock");
  189. eqnice!("sherlock\x00", cmd.stdout());
  190. });
  191. // See: https://github.com/BurntSushi/ripgrep/issues/89
  192. rgtest!(f89_files_without_match, |dir: Dir, mut cmd: TestCommand| {
  193. dir.create("sherlock", SHERLOCK);
  194. dir.create("file.py", "foo");
  195. cmd.arg("--null").arg("--files-without-match").arg("Sherlock");
  196. eqnice!("file.py\x00", cmd.stdout());
  197. });
  198. // See: https://github.com/BurntSushi/ripgrep/issues/89
  199. rgtest!(f89_count, |dir: Dir, mut cmd: TestCommand| {
  200. dir.create("sherlock", SHERLOCK);
  201. cmd.arg("--null").arg("--count").arg("Sherlock");
  202. eqnice!("sherlock\x002\n", cmd.stdout());
  203. });
  204. // See: https://github.com/BurntSushi/ripgrep/issues/89
  205. rgtest!(f89_files, |dir: Dir, mut cmd: TestCommand| {
  206. dir.create("sherlock", SHERLOCK);
  207. eqnice!("sherlock\x00", cmd.arg("--null").arg("--files").stdout());
  208. });
  209. // See: https://github.com/BurntSushi/ripgrep/issues/89
  210. rgtest!(f89_match, |dir: Dir, mut cmd: TestCommand| {
  211. dir.create("sherlock", SHERLOCK);
  212. let expected = "\
  213. sherlock\x00For the Doctor Watsons of this world, as opposed to the Sherlock
  214. sherlock\x00Holmeses, success in the province of detective work must always
  215. sherlock\x00be, to a very large extent, the result of luck. Sherlock Holmes
  216. sherlock\x00can extract a clew from a wisp of straw or a flake of cigar ash;
  217. ";
  218. eqnice!(expected, cmd.arg("--null").arg("-C1").arg("Sherlock").stdout());
  219. });
  220. // See: https://github.com/BurntSushi/ripgrep/issues/109
  221. rgtest!(f109_max_depth, |dir: Dir, mut cmd: TestCommand| {
  222. dir.create_dir("one");
  223. dir.create("one/pass", "far");
  224. dir.create_dir("one/too");
  225. dir.create("one/too/many", "far");
  226. cmd.arg("--maxdepth").arg("2").arg("far");
  227. eqnice!("one/pass:far\n", cmd.stdout());
  228. });
  229. // See: https://github.com/BurntSushi/ripgrep/issues/124
  230. rgtest!(f109_case_sensitive_part1, |dir: Dir, mut cmd: TestCommand| {
  231. dir.create("foo", "tEsT");
  232. cmd.arg("--smart-case").arg("--case-sensitive").arg("test").assert_err();
  233. });
  234. // See: https://github.com/BurntSushi/ripgrep/issues/124
  235. rgtest!(f109_case_sensitive_part2, |dir: Dir, mut cmd: TestCommand| {
  236. dir.create("foo", "tEsT");
  237. cmd.arg("--ignore-case").arg("--case-sensitive").arg("test").assert_err();
  238. });
  239. // See: https://github.com/BurntSushi/ripgrep/issues/129
  240. rgtest!(f129_matches, |dir: Dir, mut cmd: TestCommand| {
  241. dir.create("foo", "test\ntest abcdefghijklmnopqrstuvwxyz test");
  242. let expected = "foo:test\nfoo:[Omitted long matching line]\n";
  243. eqnice!(expected, cmd.arg("-M26").arg("test").stdout());
  244. });
  245. // See: https://github.com/BurntSushi/ripgrep/issues/129
  246. rgtest!(f129_context, |dir: Dir, mut cmd: TestCommand| {
  247. dir.create("foo", "test\nabcdefghijklmnopqrstuvwxyz");
  248. let expected = "foo:test\nfoo-[Omitted long context line]\n";
  249. eqnice!(expected, cmd.arg("-M20").arg("-C1").arg("test").stdout());
  250. });
  251. // See: https://github.com/BurntSushi/ripgrep/issues/129
  252. rgtest!(f129_replace, |dir: Dir, mut cmd: TestCommand| {
  253. dir.create("foo", "test\ntest abcdefghijklmnopqrstuvwxyz test");
  254. let expected = "foo:foo\nfoo:[Omitted long line with 2 matches]\n";
  255. eqnice!(expected, cmd.arg("-M26").arg("-rfoo").arg("test").stdout());
  256. });
  257. // See: https://github.com/BurntSushi/ripgrep/issues/159
  258. rgtest!(f159_max_count, |dir: Dir, mut cmd: TestCommand| {
  259. dir.create("foo", "test\ntest");
  260. eqnice!("foo:test\n", cmd.arg("-m1").arg("test").stdout());
  261. });
  262. // See: https://github.com/BurntSushi/ripgrep/issues/159
  263. rgtest!(f159_max_count_zero, |dir: Dir, mut cmd: TestCommand| {
  264. dir.create("foo", "test\ntest");
  265. cmd.arg("-m0").arg("test").assert_err();
  266. });
  267. // See: https://github.com/BurntSushi/ripgrep/issues/196
  268. rgtest!(f196_persistent_config, |dir: Dir, mut cmd: TestCommand| {
  269. dir.create("sherlock", SHERLOCK);
  270. cmd.arg("sherlock").arg("sherlock");
  271. // Make sure we get no matches by default.
  272. cmd.assert_err();
  273. // Now add our config file, and make sure it impacts ripgrep.
  274. dir.create(".ripgreprc", "--ignore-case");
  275. cmd.cmd().env("RIPGREP_CONFIG_PATH", ".ripgreprc");
  276. let expected = "\
  277. For the Doctor Watsons of this world, as opposed to the Sherlock
  278. be, to a very large extent, the result of luck. Sherlock Holmes
  279. ";
  280. eqnice!(expected, cmd.stdout());
  281. });
  282. // See: https://github.com/BurntSushi/ripgrep/issues/243
  283. rgtest!(f243_column_line, |dir: Dir, mut cmd: TestCommand| {
  284. dir.create("foo", "test");
  285. eqnice!("foo:1:1:test\n", cmd.arg("--column").arg("test").stdout());
  286. });
  287. // See: https://github.com/BurntSushi/ripgrep/issues/263
  288. rgtest!(f263_sort_files, |dir: Dir, mut cmd: TestCommand| {
  289. dir.create("foo", "test");
  290. dir.create("abc", "test");
  291. dir.create("zoo", "test");
  292. dir.create("bar", "test");
  293. let expected = "abc:test\nbar:test\nfoo:test\nzoo:test\n";
  294. eqnice!(expected, cmd.arg("--sort-files").arg("test").stdout());
  295. });
  296. // See: https://github.com/BurntSushi/ripgrep/issues/275
  297. rgtest!(f275_pathsep, |dir: Dir, mut cmd: TestCommand| {
  298. dir.create_dir("foo");
  299. dir.create("foo/bar", "test");
  300. cmd.arg("test").arg("--path-separator").arg("Z");
  301. eqnice!("fooZbar:test\n", cmd.stdout());
  302. });
  303. // See: https://github.com/BurntSushi/ripgrep/issues/362
  304. rgtest!(f362_dfa_size_limit, |dir: Dir, mut cmd: TestCommand| {
  305. dir.create("sherlock", SHERLOCK);
  306. // This should fall back to the nfa engine but should still produce the
  307. // expected result.
  308. cmd.arg("--dfa-size-limit").arg("10").arg(r"For\s").arg("sherlock");
  309. let expected = "\
  310. For the Doctor Watsons of this world, as opposed to the Sherlock
  311. ";
  312. eqnice!(expected, cmd.stdout());
  313. });
  314. // See: https://github.com/BurntSushi/ripgrep/issues/362
  315. rgtest!(f362_exceeds_regex_size_limit, |dir: Dir, mut cmd: TestCommand| {
  316. // --regex-size-limit doesn't apply to PCRE2.
  317. if dir.is_pcre2() {
  318. return;
  319. }
  320. cmd.arg("--regex-size-limit").arg("10K").arg(r"[0-9]\w+").assert_err();
  321. });
  322. // See: https://github.com/BurntSushi/ripgrep/issues/362
  323. #[cfg(target_pointer_width = "32")]
  324. rgtest!(
  325. f362_u64_to_narrow_usize_overflow,
  326. |dir: Dir, mut cmd: TestCommand| {
  327. // --dfa-size-limit doesn't apply to PCRE2.
  328. if dir.is_pcre2() {
  329. return;
  330. }
  331. dir.create_size("foo", 1000000);
  332. // 2^35 * 2^20 is ok for u64, but not for usize
  333. cmd.arg("--dfa-size-limit").arg("34359738368M").arg("--files");
  334. cmd.assert_err();
  335. }
  336. );
  337. // See: https://github.com/BurntSushi/ripgrep/issues/411
  338. rgtest!(
  339. f411_single_threaded_search_stats,
  340. |dir: Dir, mut cmd: TestCommand| {
  341. dir.create("sherlock", SHERLOCK);
  342. let lines = cmd.arg("--stats").arg("Sherlock").stdout();
  343. assert!(lines.contains("2 matched lines"));
  344. assert!(lines.contains("1 files contained matches"));
  345. assert!(lines.contains("1 files searched"));
  346. assert!(lines.contains("seconds"));
  347. }
  348. );
  349. rgtest!(f411_parallel_search_stats, |dir: Dir, mut cmd: TestCommand| {
  350. dir.create("sherlock_1", SHERLOCK);
  351. dir.create("sherlock_2", SHERLOCK);
  352. let lines = cmd.arg("--stats").arg("Sherlock").stdout();
  353. assert!(lines.contains("4 matched lines"));
  354. assert!(lines.contains("2 files contained matches"));
  355. assert!(lines.contains("2 files searched"));
  356. assert!(lines.contains("seconds"));
  357. });
  358. // See: https://github.com/BurntSushi/ripgrep/issues/416
  359. rgtest!(f416_crlf, |dir: Dir, mut cmd: TestCommand| {
  360. dir.create("sherlock", SHERLOCK_CRLF);
  361. cmd.arg("--crlf").arg(r"Sherlock$").arg("sherlock");
  362. let expected = "\
  363. For the Doctor Watsons of this world, as opposed to the Sherlock\r
  364. ";
  365. eqnice!(expected, cmd.stdout());
  366. });
  367. // See: https://github.com/BurntSushi/ripgrep/issues/416
  368. rgtest!(f416_crlf_multiline, |dir: Dir, mut cmd: TestCommand| {
  369. dir.create("sherlock", SHERLOCK_CRLF);
  370. cmd.arg("--crlf").arg("-U").arg(r"Sherlock$").arg("sherlock");
  371. let expected = "\
  372. For the Doctor Watsons of this world, as opposed to the Sherlock\r
  373. ";
  374. eqnice!(expected, cmd.stdout());
  375. });
  376. // See: https://github.com/BurntSushi/ripgrep/issues/416
  377. rgtest!(f416_crlf_only_matching, |dir: Dir, mut cmd: TestCommand| {
  378. dir.create("sherlock", SHERLOCK_CRLF);
  379. cmd.arg("--crlf").arg("-o").arg(r"Sherlock$").arg("sherlock");
  380. let expected = "\
  381. Sherlock\r
  382. ";
  383. eqnice!(expected, cmd.stdout());
  384. });
  385. // See: https://github.com/BurntSushi/ripgrep/issues/419
  386. rgtest!(f419_zero_as_shortcut_for_null, |dir: Dir, mut cmd: TestCommand| {
  387. dir.create("sherlock", SHERLOCK);
  388. cmd.arg("-0").arg("--count").arg("Sherlock");
  389. eqnice!("sherlock\x002\n", cmd.stdout());
  390. });
  391. rgtest!(f740_passthru, |dir: Dir, mut cmd: TestCommand| {
  392. dir.create("file", "\nfoo\nbar\nfoobar\n\nbaz\n");
  393. dir.create("patterns", "foo\nbar\n");
  394. // We can't assume that the way colour specs are translated to ANSI
  395. // sequences will remain stable, and --replace doesn't currently work with
  396. // pass-through, so for now we don't actually test the match sub-strings
  397. let common_args = &["-n", "--passthru"];
  398. let foo_expected = "\
  399. 1-
  400. 2:foo
  401. 3-bar
  402. 4:foobar
  403. 5-
  404. 6-baz
  405. ";
  406. // With single pattern
  407. cmd.args(common_args).arg("foo").arg("file");
  408. eqnice!(foo_expected, cmd.stdout());
  409. let foo_bar_expected = "\
  410. 1-
  411. 2:foo
  412. 3:bar
  413. 4:foobar
  414. 5-
  415. 6-baz
  416. ";
  417. // With multiple -e patterns
  418. let mut cmd = dir.command();
  419. cmd.args(common_args);
  420. cmd.args(&["-e", "foo", "-e", "bar", "file"]);
  421. eqnice!(foo_bar_expected, cmd.stdout());
  422. // With multiple -f patterns
  423. let mut cmd = dir.command();
  424. cmd.args(common_args);
  425. cmd.args(&["-f", "patterns", "file"]);
  426. eqnice!(foo_bar_expected, cmd.stdout());
  427. // -c should override
  428. let mut cmd = dir.command();
  429. cmd.args(common_args);
  430. cmd.args(&["-c", "foo", "file"]);
  431. eqnice!("2\n", cmd.stdout());
  432. let only_foo_expected = "\
  433. 1-
  434. 2:foo
  435. 3-bar
  436. 4:foo
  437. 5-
  438. 6-baz
  439. ";
  440. // -o should work
  441. let mut cmd = dir.command();
  442. cmd.args(common_args);
  443. cmd.args(&["-o", "foo", "file"]);
  444. eqnice!(only_foo_expected, cmd.stdout());
  445. let replace_foo_expected = "\
  446. 1-
  447. 2:wat
  448. 3-bar
  449. 4:watbar
  450. 5-
  451. 6-baz
  452. ";
  453. // -r should work
  454. let mut cmd = dir.command();
  455. cmd.args(common_args);
  456. cmd.args(&["-r", "wat", "foo", "file"]);
  457. eqnice!(replace_foo_expected, cmd.stdout());
  458. });
  459. // See: https://github.com/BurntSushi/ripgrep/issues/948
  460. rgtest!(f948_exit_code_match, |dir: Dir, mut cmd: TestCommand| {
  461. dir.create("sherlock", SHERLOCK);
  462. cmd.arg(".");
  463. cmd.assert_exit_code(0);
  464. });
  465. // See: https://github.com/BurntSushi/ripgrep/issues/948
  466. rgtest!(f948_exit_code_no_match, |dir: Dir, mut cmd: TestCommand| {
  467. dir.create("sherlock", SHERLOCK);
  468. cmd.arg("NADA");
  469. cmd.assert_exit_code(1);
  470. });
  471. // See: https://github.com/BurntSushi/ripgrep/issues/948
  472. rgtest!(f948_exit_code_error, |dir: Dir, mut cmd: TestCommand| {
  473. dir.create("sherlock", SHERLOCK);
  474. cmd.arg("*");
  475. cmd.assert_exit_code(2);
  476. });
  477. // See: https://github.com/BurntSushi/ripgrep/issues/917
  478. rgtest!(f917_trim, |dir: Dir, mut cmd: TestCommand| {
  479. const SHERLOCK: &'static str = "\
  480. zzz
  481. For the Doctor Watsons of this world, as opposed to the Sherlock
  482. Holmeses, success in the province of detective work must always
  483. \tbe, to a very large extent, the result of luck. Sherlock Holmes
  484. can extract a clew from a wisp of straw or a flake of cigar ash;
  485. but Doctor Watson has to have it taken out for him and dusted,
  486. and exhibited clearly, with a label attached.
  487. ";
  488. dir.create("sherlock", SHERLOCK);
  489. cmd.args(&["-n", "-B1", "-A2", "--trim", "Holmeses", "sherlock"]);
  490. let expected = "\
  491. 2-For the Doctor Watsons of this world, as opposed to the Sherlock
  492. 3:Holmeses, success in the province of detective work must always
  493. 4-be, to a very large extent, the result of luck. Sherlock Holmes
  494. 5-can extract a clew from a wisp of straw or a flake of cigar ash;
  495. ";
  496. eqnice!(expected, cmd.stdout());
  497. });
  498. // See: https://github.com/BurntSushi/ripgrep/issues/917
  499. //
  500. // This is like f917_trim, except this tests that trimming occurs even when the
  501. // whitespace is part of a match.
  502. rgtest!(f917_trim_match, |dir: Dir, mut cmd: TestCommand| {
  503. const SHERLOCK: &'static str = "\
  504. zzz
  505. For the Doctor Watsons of this world, as opposed to the Sherlock
  506. Holmeses, success in the province of detective work must always
  507. \tbe, to a very large extent, the result of luck. Sherlock Holmes
  508. can extract a clew from a wisp of straw or a flake of cigar ash;
  509. but Doctor Watson has to have it taken out for him and dusted,
  510. and exhibited clearly, with a label attached.
  511. ";
  512. dir.create("sherlock", SHERLOCK);
  513. cmd.args(&["-n", "-B1", "-A2", "--trim", r"\s+Holmeses", "sherlock"]);
  514. let expected = "\
  515. 2-For the Doctor Watsons of this world, as opposed to the Sherlock
  516. 3:Holmeses, success in the province of detective work must always
  517. 4-be, to a very large extent, the result of luck. Sherlock Holmes
  518. 5-can extract a clew from a wisp of straw or a flake of cigar ash;
  519. ";
  520. eqnice!(expected, cmd.stdout());
  521. });
  522. // See: https://github.com/BurntSushi/ripgrep/issues/993
  523. rgtest!(f993_null_data, |dir: Dir, mut cmd: TestCommand| {
  524. dir.create("test", "foo\x00bar\x00\x00\x00baz\x00");
  525. cmd.arg("--null-data").arg(r".+").arg("test");
  526. // If we just used -a instead of --null-data, then the result would include
  527. // all NUL bytes.
  528. let expected = "foo\x00bar\x00baz\x00";
  529. eqnice!(expected, cmd.stdout());
  530. });
  531. // See: https://github.com/BurntSushi/ripgrep/issues/1078
  532. //
  533. // N.B. There are many more tests in the grep-printer crate.
  534. rgtest!(f1078_max_columns_preview1, |dir: Dir, mut cmd: TestCommand| {
  535. dir.create("sherlock", SHERLOCK);
  536. cmd.args(&[
  537. "-M46",
  538. "--max-columns-preview",
  539. "exhibited|dusted|has to have it",
  540. ]);
  541. let expected = "\
  542. sherlock:but Doctor Watson has to have it taken out for [... omitted end of long line]
  543. sherlock:and exhibited clearly, with a label attached.
  544. ";
  545. eqnice!(expected, cmd.stdout());
  546. });
  547. rgtest!(f1078_max_columns_preview2, |dir: Dir, mut cmd: TestCommand| {
  548. dir.create("sherlock", SHERLOCK);
  549. cmd.args(&[
  550. "-M43",
  551. "--max-columns-preview",
  552. // Doing a replacement forces ripgrep to show the number of remaining
  553. // matches. Normally, this happens by default when printing a tty with
  554. // colors.
  555. "-rxxx",
  556. "exhibited|dusted|has to have it",
  557. ]);
  558. let expected = "\
  559. sherlock:but Doctor Watson xxx taken out for him and [... 1 more match]
  560. sherlock:and xxx clearly, with a label attached.
  561. ";
  562. eqnice!(expected, cmd.stdout());
  563. });
  564. // See: https://github.com/BurntSushi/ripgrep/issues/1138
  565. rgtest!(f1138_no_ignore_dot, |dir: Dir, mut cmd: TestCommand| {
  566. dir.create_dir(".git");
  567. dir.create(".gitignore", "foo");
  568. dir.create(".ignore", "bar");
  569. dir.create(".fzf-ignore", "quux");
  570. dir.create("foo", "");
  571. dir.create("bar", "");
  572. dir.create("quux", "");
  573. cmd.arg("--sort").arg("path").arg("--files");
  574. eqnice!("quux\n", cmd.stdout());
  575. eqnice!("bar\nquux\n", cmd.arg("--no-ignore-dot").stdout());
  576. eqnice!("bar\n", cmd.arg("--ignore-file").arg(".fzf-ignore").stdout());
  577. });
  578. // See: https://github.com/BurntSushi/ripgrep/issues/1155
  579. rgtest!(f1155_auto_hybrid_regex, |dir: Dir, mut cmd: TestCommand| {
  580. // No sense in testing a hybrid regex engine with only one engine!
  581. if !dir.is_pcre2() {
  582. return;
  583. }
  584. dir.create("sherlock", SHERLOCK);
  585. cmd.arg("--no-pcre2").arg("--auto-hybrid-regex").arg(r"(?<=the )Sherlock");
  586. let expected = "\
  587. sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
  588. ";
  589. eqnice!(expected, cmd.stdout());
  590. });
  591. // See: https://github.com/BurntSushi/ripgrep/issues/1207
  592. //
  593. // Tests if without encoding 'none' flag null bytes are consumed by automatic
  594. // encoding detection.
  595. rgtest!(f1207_auto_encoding, |dir: Dir, mut cmd: TestCommand| {
  596. dir.create_bytes("foo", b"\xFF\xFE\x00\x62");
  597. cmd.arg("-a").arg("\\x00").arg("foo");
  598. cmd.assert_exit_code(1);
  599. });
  600. // See: https://github.com/BurntSushi/ripgrep/issues/1207
  601. //
  602. // Tests if encoding 'none' flag does treat file as raw bytes
  603. rgtest!(f1207_ignore_encoding, |dir: Dir, mut cmd: TestCommand| {
  604. // PCRE2 chokes on this test because it can't search invalid non-UTF-8
  605. // and the point of this test is to search raw UTF-16.
  606. if dir.is_pcre2() {
  607. return;
  608. }
  609. dir.create_bytes("foo", b"\xFF\xFE\x00\x62");
  610. cmd.arg("--encoding").arg("none").arg("-a").arg("\\x00").arg("foo");
  611. eqnice!("\u{FFFD}\u{FFFD}\x00b\n", cmd.stdout());
  612. });
  613. // See: https://github.com/BurntSushi/ripgrep/issues/1414
  614. rgtest!(f1414_no_require_git, |dir: Dir, mut cmd: TestCommand| {
  615. dir.create(".gitignore", "foo");
  616. dir.create("foo", "");
  617. dir.create("bar", "");
  618. let stdout = cmd.args(&["--sort", "path", "--files"]).stdout();
  619. eqnice!("bar\nfoo\n", stdout);
  620. let stdout =
  621. cmd.args(&["--sort", "path", "--files", "--no-require-git"]).stdout();
  622. eqnice!("bar\n", stdout);
  623. let stdout = cmd
  624. .args(&[
  625. "--sort",
  626. "path",
  627. "--files",
  628. "--no-require-git",
  629. "--require-git",
  630. ])
  631. .stdout();
  632. eqnice!("bar\nfoo\n", stdout);
  633. });
  634. // See: https://github.com/BurntSushi/ripgrep/pull/1420
  635. rgtest!(f1420_no_ignore_exclude, |dir: Dir, mut cmd: TestCommand| {
  636. dir.create_dir(".git/info");
  637. dir.create(".git/info/exclude", "foo");
  638. dir.create("bar", "");
  639. dir.create("foo", "");
  640. cmd.arg("--sort").arg("path").arg("--files");
  641. eqnice!("bar\n", cmd.stdout());
  642. eqnice!("bar\nfoo\n", cmd.arg("--no-ignore-exclude").stdout());
  643. });
  644. // See: https://github.com/BurntSushi/ripgrep/pull/1466
  645. rgtest!(f1466_no_ignore_files, |dir: Dir, mut cmd: TestCommand| {
  646. dir.create(".myignore", "bar");
  647. dir.create("bar", "");
  648. dir.create("foo", "");
  649. // Test that --no-ignore-files disables --ignore-file.
  650. // And that --ignore-files overrides --no-ignore-files.
  651. cmd.arg("--sort").arg("path").arg("--files");
  652. eqnice!("bar\nfoo\n", cmd.stdout());
  653. eqnice!("foo\n", cmd.arg("--ignore-file").arg(".myignore").stdout());
  654. eqnice!("bar\nfoo\n", cmd.arg("--no-ignore-files").stdout());
  655. eqnice!("foo\n", cmd.arg("--ignore-files").stdout());
  656. // Test that the -u flag does not disable --ignore-file.
  657. let mut cmd = dir.command();
  658. cmd.arg("--sort").arg("path").arg("--files");
  659. cmd.arg("--ignore-file").arg(".myignore");
  660. eqnice!("foo\n", cmd.stdout());
  661. eqnice!("foo\n", cmd.arg("-u").stdout());
  662. });
  663. rgtest!(no_context_sep, |dir: Dir, mut cmd: TestCommand| {
  664. dir.create("test", "foo\nctx\nbar\nctx\nfoo\nctx");
  665. cmd.args(&["-A1", "--no-context-separator", "foo", "test"]);
  666. eqnice!("foo\nctx\nfoo\nctx\n", cmd.stdout());
  667. });
  668. rgtest!(no_context_sep_overrides, |dir: Dir, mut cmd: TestCommand| {
  669. dir.create("test", "foo\nctx\nbar\nctx\nfoo\nctx");
  670. cmd.args(&[
  671. "-A1",
  672. "--context-separator",
  673. "AAA",
  674. "--no-context-separator",
  675. "foo",
  676. "test",
  677. ]);
  678. eqnice!("foo\nctx\nfoo\nctx\n", cmd.stdout());
  679. });
  680. rgtest!(no_context_sep_overridden, |dir: Dir, mut cmd: TestCommand| {
  681. dir.create("test", "foo\nctx\nbar\nctx\nfoo\nctx");
  682. cmd.args(&[
  683. "-A1",
  684. "--no-context-separator",
  685. "--context-separator",
  686. "AAA",
  687. "foo",
  688. "test",
  689. ]);
  690. eqnice!("foo\nctx\nAAA\nfoo\nctx\n", cmd.stdout());
  691. });
  692. rgtest!(context_sep, |dir: Dir, mut cmd: TestCommand| {
  693. dir.create("test", "foo\nctx\nbar\nctx\nfoo\nctx");
  694. cmd.args(&["-A1", "--context-separator", "AAA", "foo", "test"]);
  695. eqnice!("foo\nctx\nAAA\nfoo\nctx\n", cmd.stdout());
  696. });
  697. rgtest!(context_sep_default, |dir: Dir, mut cmd: TestCommand| {
  698. dir.create("test", "foo\nctx\nbar\nctx\nfoo\nctx");
  699. cmd.args(&["-A1", "foo", "test"]);
  700. eqnice!("foo\nctx\n--\nfoo\nctx\n", cmd.stdout());
  701. });
  702. rgtest!(context_sep_empty, |dir: Dir, mut cmd: TestCommand| {
  703. dir.create("test", "foo\nctx\nbar\nctx\nfoo\nctx");
  704. cmd.args(&["-A1", "--context-separator", "", "foo", "test"]);
  705. eqnice!("foo\nctx\n\nfoo\nctx\n", cmd.stdout());
  706. });
  707. rgtest!(no_unicode, |dir: Dir, mut cmd: TestCommand| {
  708. dir.create("test", "δ");
  709. cmd.arg("-i").arg("--no-unicode").arg("Δ").assert_err();
  710. });