summaryrefslogtreecommitdiffstats
path: root/tests/bfs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/bfs')
-rw-r--r--tests/bfs/D_all.out19
-rw-r--r--tests/bfs/D_all.sh1
-rw-r--r--tests/bfs/D_incomplete.sh1
-rw-r--r--tests/bfs/D_multi.out19
-rw-r--r--tests/bfs/D_multi.sh1
-rw-r--r--tests/bfs/D_opt.out7
-rw-r--r--tests/bfs/D_opt.sh1
-rw-r--r--tests/bfs/D_unknown.out19
-rw-r--r--tests/bfs/D_unknown.sh4
-rw-r--r--tests/bfs/L_capable.out2
-rw-r--r--tests/bfs/L_capable.sh10
-rw-r--r--tests/bfs/L_unique.out1
-rw-r--r--tests/bfs/L_unique.sh1
-rw-r--r--tests/bfs/L_unique_depth.out3
-rw-r--r--tests/bfs/L_unique_depth.sh1
-rw-r--r--tests/bfs/L_unique_loops.out3
-rw-r--r--tests/bfs/L_unique_loops.sh1
-rw-r--r--tests/bfs/O0.out19
-rw-r--r--tests/bfs/O0.sh1
-rw-r--r--tests/bfs/O1.out19
-rw-r--r--tests/bfs/O1.sh1
-rw-r--r--tests/bfs/O2.out19
-rw-r--r--tests/bfs/O2.sh1
-rw-r--r--tests/bfs/O3.out19
-rw-r--r--tests/bfs/O3.sh1
-rw-r--r--tests/bfs/O9.out19
-rw-r--r--tests/bfs/O9.sh4
-rw-r--r--tests/bfs/Ofast.out19
-rw-r--r--tests/bfs/Ofast.sh1
-rw-r--r--tests/bfs/S_bfs.out19
-rw-r--r--tests/bfs/S_bfs.sh2
-rw-r--r--tests/bfs/S_dfs.out19
-rw-r--r--tests/bfs/S_dfs.sh2
-rw-r--r--tests/bfs/S_ids.out19
-rw-r--r--tests/bfs/S_ids.sh2
-rw-r--r--tests/bfs/and_incomplete.sh1
-rw-r--r--tests/bfs/capable.out1
-rw-r--r--tests/bfs/capable.sh10
-rw-r--r--tests/bfs/closed_stderr.sh4
-rw-r--r--tests/bfs/closed_stdin.out19
-rw-r--r--tests/bfs/closed_stdin.sh1
-rw-r--r--tests/bfs/closed_stdout.sh4
-rw-r--r--tests/bfs/color.out27
-rw-r--r--tests/bfs/color.sh1
-rw-r--r--tests/bfs/color_L.out27
-rw-r--r--tests/bfs/color_L.sh1
-rw-r--r--tests/bfs/color_L_ln_target.out27
-rw-r--r--tests/bfs/color_L_ln_target.sh1
-rw-r--r--tests/bfs/color_L_no_stat.out27
-rw-r--r--tests/bfs/color_L_no_stat.sh1
-rw-r--r--tests/bfs/color_auto.out27
-rw-r--r--tests/bfs/color_auto.sh4
-rw-r--r--tests/bfs/color_cd0_no.out27
-rw-r--r--tests/bfs/color_cd0_no.sh1
-rw-r--r--tests/bfs/color_deep.out16
-rw-r--r--tests/bfs/color_deep.sh7
-rw-r--r--tests/bfs/color_escapes.out27
-rw-r--r--tests/bfs/color_escapes.sh1
-rw-r--r--tests/bfs/color_ext.out27
-rw-r--r--tests/bfs/color_ext.sh1
-rw-r--r--tests/bfs/color_ext0.out27
-rw-r--r--tests/bfs/color_ext0.sh1
-rw-r--r--tests/bfs/color_ext_case.out27
-rw-r--r--tests/bfs/color_ext_case.sh6
-rw-r--r--tests/bfs/color_ext_override.out27
-rw-r--r--tests/bfs/color_ext_override.sh1
-rw-r--r--tests/bfs/color_ext_underride.out27
-rw-r--r--tests/bfs/color_ext_underride.sh1
-rw-r--r--tests/bfs/color_fi0_no.out27
-rw-r--r--tests/bfs/color_fi0_no.sh1
-rw-r--r--tests/bfs/color_fi_no.out27
-rw-r--r--tests/bfs/color_fi_no.sh1
-rw-r--r--tests/bfs/color_ln_target.out27
-rw-r--r--tests/bfs/color_ln_target.sh1
-rw-r--r--tests/bfs/color_ls.out12
-rw-r--r--tests/bfs/color_ls.sh15
-rw-r--r--tests/bfs/color_mh.out27
-rw-r--r--tests/bfs/color_mh.sh1
-rw-r--r--tests/bfs/color_mh0.out27
-rw-r--r--tests/bfs/color_mh0.sh1
-rw-r--r--tests/bfs/color_mi.out27
-rw-r--r--tests/bfs/color_mi.sh1
-rw-r--r--tests/bfs/color_missing_colon.out27
-rw-r--r--tests/bfs/color_missing_colon.sh1
-rw-r--r--tests/bfs/color_no.out27
-rw-r--r--tests/bfs/color_no.sh1
-rw-r--r--tests/bfs/color_no_stat.out27
-rw-r--r--tests/bfs/color_no_stat.sh1
-rw-r--r--tests/bfs/color_nul.out27
-rw-r--r--tests/bfs/color_nul.sh3
-rw-r--r--tests/bfs/color_or.out27
-rw-r--r--tests/bfs/color_or.sh1
-rw-r--r--tests/bfs/color_or0_mi.out27
-rw-r--r--tests/bfs/color_or0_mi.sh1
-rw-r--r--tests/bfs/color_or0_mi0.out27
-rw-r--r--tests/bfs/color_or0_mi0.sh1
-rw-r--r--tests/bfs/color_or_mi.out27
-rw-r--r--tests/bfs/color_or_mi.sh1
-rw-r--r--tests/bfs/color_or_mi0.out27
-rw-r--r--tests/bfs/color_or_mi0.sh1
-rw-r--r--tests/bfs/color_rs_lc_rc_ec.out27
-rw-r--r--tests/bfs/color_rs_lc_rc_ec.sh1
-rw-r--r--tests/bfs/color_st0_tw0_ow.out27
-rw-r--r--tests/bfs/color_st0_tw0_ow.sh1
-rw-r--r--tests/bfs/color_st0_tw0_ow0.out27
-rw-r--r--tests/bfs/color_st0_tw0_ow0.sh1
-rw-r--r--tests/bfs/color_st0_tw_ow.out27
-rw-r--r--tests/bfs/color_st0_tw_ow.sh1
-rw-r--r--tests/bfs/color_st0_tw_ow0.out27
-rw-r--r--tests/bfs/color_st0_tw_ow0.sh1
-rw-r--r--tests/bfs/color_st_tw0_ow.out27
-rw-r--r--tests/bfs/color_st_tw0_ow.sh1
-rw-r--r--tests/bfs/color_st_tw0_ow0.out27
-rw-r--r--tests/bfs/color_st_tw0_ow0.sh1
-rw-r--r--tests/bfs/color_st_tw_ow0.out27
-rw-r--r--tests/bfs/color_st_tw_ow0.sh1
-rw-r--r--tests/bfs/color_star.sh2
-rw-r--r--tests/bfs/color_su0_sg.out27
-rw-r--r--tests/bfs/color_su0_sg.sh1
-rw-r--r--tests/bfs/color_su0_sg0.out27
-rw-r--r--tests/bfs/color_su0_sg0.sh1
-rw-r--r--tests/bfs/color_su_sg0.out27
-rw-r--r--tests/bfs/color_su_sg0.sh1
-rw-r--r--tests/bfs/comma_incomplete.sh1
-rw-r--r--tests/bfs/data_flow_hidden.out19
-rw-r--r--tests/bfs/data_flow_hidden.sh1
-rw-r--r--tests/bfs/deep_strict.out16
-rw-r--r--tests/bfs/deep_strict.sh3
-rw-r--r--tests/bfs/exclude_depth.out13
-rw-r--r--tests/bfs/exclude_depth.sh1
-rw-r--r--tests/bfs/exclude_exclude.sh1
-rw-r--r--tests/bfs/exclude_mindepth.out0
-rw-r--r--tests/bfs/exclude_mindepth.sh1
-rw-r--r--tests/bfs/exclude_name.out13
-rw-r--r--tests/bfs/exclude_name.sh1
-rw-r--r--tests/bfs/exclude_print.sh1
-rw-r--r--tests/bfs/exec_flush_fprint.out1
-rw-r--r--tests/bfs/exec_flush_fprint.sh2
-rw-r--r--tests/bfs/exec_flush_fprint_fail.sh2
-rw-r--r--tests/bfs/execdir_plus.out11
-rw-r--r--tests/bfs/execdir_plus.sh4
-rw-r--r--tests/bfs/execdir_plus_nonexistent.out19
-rw-r--r--tests/bfs/execdir_plus_nonexistent.sh2
-rw-r--r--tests/bfs/expr_flag_path.out2
-rw-r--r--tests/bfs/expr_flag_path.sh1
-rw-r--r--tests/bfs/expr_path_flag.out2
-rw-r--r--tests/bfs/expr_path_flag.sh1
-rw-r--r--tests/bfs/flag_expr_path.out2
-rw-r--r--tests/bfs/flag_expr_path.sh1
-rw-r--r--tests/bfs/fprint_duplicate_stdout.out38
-rw-r--r--tests/bfs/fprint_duplicate_stdout.sh3
-rw-r--r--tests/bfs/fprint_error_stderr.sh2
-rw-r--r--tests/bfs/fprint_error_stdout.sh2
-rw-r--r--tests/bfs/help.sh4
-rw-r--r--tests/bfs/hidden.out1
-rw-r--r--tests/bfs/hidden.sh1
-rw-r--r--tests/bfs/hidden_root.out5
-rw-r--r--tests/bfs/hidden_root.sh2
-rw-r--r--tests/bfs/high_byte.sh1
-rw-r--r--tests/bfs/j0.sh1
-rw-r--r--tests/bfs/j1.out19
-rw-r--r--tests/bfs/j1.sh1
-rw-r--r--tests/bfs/j64.out19
-rw-r--r--tests/bfs/j64.sh1
-rw-r--r--tests/bfs/j_negative.sh1
-rw-r--r--tests/bfs/limit.out4
-rw-r--r--tests/bfs/limit.sh1
-rw-r--r--tests/bfs/limit_0.sh1
-rw-r--r--tests/bfs/limit_implicit_print.sh1
-rw-r--r--tests/bfs/limit_incomplete.sh1
-rw-r--r--tests/bfs/limit_one.sh1
-rw-r--r--tests/bfs/links_empty.sh1
-rw-r--r--tests/bfs/links_invalid.sh1
-rw-r--r--tests/bfs/links_leading_space.sh1
-rw-r--r--tests/bfs/links_negative.sh1
-rw-r--r--tests/bfs/links_noarg.sh1
-rw-r--r--tests/bfs/newerma_nonexistent.sh1
-rw-r--r--tests/bfs/newermq.sh1
-rw-r--r--tests/bfs/newermt_invalid.sh1
-rw-r--r--tests/bfs/newerqm.sh1
-rw-r--r--tests/bfs/nocolor.out27
-rw-r--r--tests/bfs/nocolor.sh1
-rw-r--r--tests/bfs/nocolor_env.out27
-rw-r--r--tests/bfs/nocolor_env.sh3
-rw-r--r--tests/bfs/nocolor_env_empty.out27
-rw-r--r--tests/bfs/nocolor_env_empty.sh3
-rw-r--r--tests/bfs/nohidden.out21
-rw-r--r--tests/bfs/nohidden.sh1
-rw-r--r--tests/bfs/nohidden_depth.out21
-rw-r--r--tests/bfs/nohidden_depth.sh1
-rw-r--r--tests/bfs/nowarn.sh2
-rw-r--r--tests/bfs/ok_plus_semicolon.out19
-rw-r--r--tests/bfs/ok_plus_semicolon.sh8
-rw-r--r--tests/bfs/okdir_plus_semicolon.out19
-rw-r--r--tests/bfs/okdir_plus_semicolon.sh1
-rw-r--r--tests/bfs/or_incomplete.sh1
-rw-r--r--tests/bfs/path_expr_flag.out2
-rw-r--r--tests/bfs/path_expr_flag.sh1
-rw-r--r--tests/bfs/path_flag_expr.out2
-rw-r--r--tests/bfs/path_flag_expr.sh1
-rw-r--r--tests/bfs/perm_leading_plus_symbolic.out0
-rw-r--r--tests/bfs/perm_leading_plus_symbolic.sh1
-rw-r--r--tests/bfs/perm_symbolic_double_comma.sh1
-rw-r--r--tests/bfs/perm_symbolic_missing_action.sh1
-rw-r--r--tests/bfs/perm_symbolic_trailing_comma.sh1
-rw-r--r--tests/bfs/printf_color.out28
-rw-r--r--tests/bfs/printf_color.sh1
-rw-r--r--tests/bfs/printf_duplicate_flag.sh1
-rw-r--r--tests/bfs/printf_everything.sh15
-rw-r--r--tests/bfs/printf_incomplete_escape.sh1
-rw-r--r--tests/bfs/printf_incomplete_format.sh1
-rw-r--r--tests/bfs/printf_invalid_escape.sh1
-rw-r--r--tests/bfs/printf_invalid_format.sh1
-rw-r--r--tests/bfs/printf_must_be_numeric.sh1
-rw-r--r--tests/bfs/printf_w.out0
-rw-r--r--tests/bfs/printf_w.sh2
-rw-r--r--tests/bfs/status.sh1
-rw-r--r--tests/bfs/stderr_fails_loudly.sh2
-rw-r--r--tests/bfs/stderr_fails_silently.out19
-rw-r--r--tests/bfs/stderr_fails_silently.sh2
-rw-r--r--tests/bfs/type_multi.out7
-rw-r--r--tests/bfs/type_multi.sh1
-rw-r--r--tests/bfs/typo.sh1
-rw-r--r--tests/bfs/unexpected_operator.sh1
-rw-r--r--tests/bfs/unique.out2
-rw-r--r--tests/bfs/unique.sh1
-rw-r--r--tests/bfs/unique_depth.out19
-rw-r--r--tests/bfs/unique_depth.sh1
-rw-r--r--tests/bfs/version.sh1
-rw-r--r--tests/bfs/warn_O9.out19
-rw-r--r--tests/bfs/warn_O9.sh3
-rw-r--r--tests/bfs/warn_depth_prune.sh2
-rw-r--r--tests/bfs/warn_exclude_path.sh2
-rw-r--r--tests/bfs/warn_xdev_mount.out19
-rw-r--r--tests/bfs/warn_xdev_mount.sh2
-rw-r--r--tests/bfs/xtype_depth.sh2
-rw-r--r--tests/bfs/xtype_multi.out10
-rw-r--r--tests/bfs/xtype_multi.sh1
-rw-r--r--tests/bfs/xtype_reorder.out0
-rw-r--r--tests/bfs/xtype_reorder.sh4
240 files changed, 2052 insertions, 0 deletions
diff --git a/tests/bfs/D_all.out b/tests/bfs/D_all.out
new file mode 100644
index 0000000..a7ccfe4
--- /dev/null
+++ b/tests/bfs/D_all.out
@@ -0,0 +1,19 @@
+basic
+basic/a
+basic/b
+basic/c
+basic/c/d
+basic/e
+basic/e/f
+basic/g
+basic/g/h
+basic/i
+basic/j
+basic/j/foo
+basic/k
+basic/k/foo
+basic/k/foo/bar
+basic/l
+basic/l/foo
+basic/l/foo/bar
+basic/l/foo/bar/baz
diff --git a/tests/bfs/D_all.sh b/tests/bfs/D_all.sh
new file mode 100644
index 0000000..170698a
--- /dev/null
+++ b/tests/bfs/D_all.sh
@@ -0,0 +1 @@
+bfs_diff -D all basic
diff --git a/tests/bfs/D_incomplete.sh b/tests/bfs/D_incomplete.sh
new file mode 100644
index 0000000..30c522a
--- /dev/null
+++ b/tests/bfs/D_incomplete.sh
@@ -0,0 +1 @@
+! invoke_bfs -D
diff --git a/tests/bfs/D_multi.out b/tests/bfs/D_multi.out
new file mode 100644
index 0000000..a7ccfe4
--- /dev/null
+++ b/tests/bfs/D_multi.out
@@ -0,0 +1,19 @@
+basic
+basic/a
+basic/b
+basic/c
+basic/c/d
+basic/e
+basic/e/f
+basic/g
+basic/g/h
+basic/i
+basic/j
+basic/j/foo
+basic/k
+basic/k/foo
+basic/k/foo/bar
+basic/l
+basic/l/foo
+basic/l/foo/bar
+basic/l/foo/bar/baz
diff --git a/tests/bfs/D_multi.sh b/tests/bfs/D_multi.sh
new file mode 100644
index 0000000..08a8ca6
--- /dev/null
+++ b/tests/bfs/D_multi.sh
@@ -0,0 +1 @@
+bfs_diff -D opt,tree,unknown basic
diff --git a/tests/bfs/D_opt.out b/tests/bfs/D_opt.out
new file mode 100644
index 0000000..6218a0c
--- /dev/null
+++ b/tests/bfs/D_opt.out
@@ -0,0 +1,7 @@
+basic/a
+basic/b
+basic/c/d
+basic/e/f
+basic/j/foo
+basic/k/foo/bar
+basic/l/foo/bar/baz
diff --git a/tests/bfs/D_opt.sh b/tests/bfs/D_opt.sh
new file mode 100644
index 0000000..c14fe70
--- /dev/null
+++ b/tests/bfs/D_opt.sh
@@ -0,0 +1 @@
+bfs_diff -D opt -nohidden -not \( -type c -o -type d \) -links -5 -links -10 -not -hidden basic
diff --git a/tests/bfs/D_unknown.out b/tests/bfs/D_unknown.out
new file mode 100644
index 0000000..a7ccfe4
--- /dev/null
+++ b/tests/bfs/D_unknown.out
@@ -0,0 +1,19 @@
+basic
+basic/a
+basic/b
+basic/c
+basic/c/d
+basic/e
+basic/e/f
+basic/g
+basic/g/h
+basic/i
+basic/j
+basic/j/foo
+basic/k
+basic/k/foo
+basic/k/foo/bar
+basic/l
+basic/l/foo
+basic/l/foo/bar
+basic/l/foo/bar/baz
diff --git a/tests/bfs/D_unknown.sh b/tests/bfs/D_unknown.sh
new file mode 100644
index 0000000..cac9bd9
--- /dev/null
+++ b/tests/bfs/D_unknown.sh
@@ -0,0 +1,4 @@
+stderr=$(invoke_bfs -warn -D unknown basic 2>&1 >"$OUT")
+[ -n "$stderr" ]
+sort_output
+diff_output
diff --git a/tests/bfs/L_capable.out b/tests/bfs/L_capable.out
new file mode 100644
index 0000000..0810d4a
--- /dev/null
+++ b/tests/bfs/L_capable.out
@@ -0,0 +1,2 @@
+./capable
+./link
diff --git a/tests/bfs/L_capable.sh b/tests/bfs/L_capable.sh
new file mode 100644
index 0000000..97c404f
--- /dev/null
+++ b/tests/bfs/L_capable.sh
@@ -0,0 +1,10 @@
+test "$UNAME" = "Linux" || skip
+invoke_bfs . -quit -capable || skip
+
+cd "$TEST"
+
+"$XTOUCH" normal capable
+bfs_sudo setcap all+ep capable || skip
+ln -s capable link
+
+bfs_diff -L . -capable
diff --git a/tests/bfs/L_unique.out b/tests/bfs/L_unique.out
new file mode 100644
index 0000000..c94c48e
--- /dev/null
+++ b/tests/bfs/L_unique.out
@@ -0,0 +1 @@
+links/file
diff --git a/tests/bfs/L_unique.sh b/tests/bfs/L_unique.sh
new file mode 100644
index 0000000..c804526
--- /dev/null
+++ b/tests/bfs/L_unique.sh
@@ -0,0 +1 @@
+bfs_diff -L links/{file,symlink,hardlink} -unique
diff --git a/tests/bfs/L_unique_depth.out b/tests/bfs/L_unique_depth.out
new file mode 100644
index 0000000..dad0a98
--- /dev/null
+++ b/tests/bfs/L_unique_depth.out
@@ -0,0 +1,3 @@
+loops/deeply/nested
+loops/deeply/nested/dir
+loops/deeply/nested/loop
diff --git a/tests/bfs/L_unique_depth.sh b/tests/bfs/L_unique_depth.sh
new file mode 100644
index 0000000..fb9aca1
--- /dev/null
+++ b/tests/bfs/L_unique_depth.sh
@@ -0,0 +1 @@
+bfs_diff -L loops/deeply/nested -unique -depth
diff --git a/tests/bfs/L_unique_loops.out b/tests/bfs/L_unique_loops.out
new file mode 100644
index 0000000..dad0a98
--- /dev/null
+++ b/tests/bfs/L_unique_loops.out
@@ -0,0 +1,3 @@
+loops/deeply/nested
+loops/deeply/nested/dir
+loops/deeply/nested/loop
diff --git a/tests/bfs/L_unique_loops.sh b/tests/bfs/L_unique_loops.sh
new file mode 100644
index 0000000..2bdd94e
--- /dev/null
+++ b/tests/bfs/L_unique_loops.sh
@@ -0,0 +1 @@
+bfs_diff -L loops/deeply/nested -unique
diff --git a/tests/bfs/O0.out b/tests/bfs/O0.out
new file mode 100644
index 0000000..a7ccfe4
--- /dev/null
+++ b/tests/bfs/O0.out
@@ -0,0 +1,19 @@
+basic
+basic/a
+basic/b
+basic/c
+basic/c/d
+basic/e
+basic/e/f
+basic/g
+basic/g/h
+basic/i
+basic/j
+basic/j/foo
+basic/k
+basic/k/foo
+basic/k/foo/bar
+basic/l
+basic/l/foo
+basic/l/foo/bar
+basic/l/foo/bar/baz
diff --git a/tests/bfs/O0.sh b/tests/bfs/O0.sh
new file mode 100644
index 0000000..0f92d71
--- /dev/null
+++ b/tests/bfs/O0.sh
@@ -0,0 +1 @@
+bfs_diff -O0 basic -not \( -type f -not -type f \)
diff --git a/tests/bfs/O1.out b/tests/bfs/O1.out
new file mode 100644
index 0000000..a7ccfe4
--- /dev/null
+++ b/tests/bfs/O1.out
@@ -0,0 +1,19 @@
+basic
+basic/a
+basic/b
+basic/c
+basic/c/d
+basic/e
+basic/e/f
+basic/g
+basic/g/h
+basic/i
+basic/j
+basic/j/foo
+basic/k
+basic/k/foo
+basic/k/foo/bar
+basic/l
+basic/l/foo
+basic/l/foo/bar
+basic/l/foo/bar/baz
diff --git a/tests/bfs/O1.sh b/tests/bfs/O1.sh
new file mode 100644
index 0000000..924b410
--- /dev/null
+++ b/tests/bfs/O1.sh
@@ -0,0 +1 @@
+bfs_diff -O1 basic -not \( -type f -not -type f \)
diff --git a/tests/bfs/O2.out b/tests/bfs/O2.out
new file mode 100644
index 0000000..a7ccfe4
--- /dev/null
+++ b/tests/bfs/O2.out
@@ -0,0 +1,19 @@
+basic
+basic/a
+basic/b
+basic/c
+basic/c/d
+basic/e
+basic/e/f
+basic/g
+basic/g/h
+basic/i
+basic/j
+basic/j/foo
+basic/k
+basic/k/foo
+basic/k/foo/bar
+basic/l
+basic/l/foo
+basic/l/foo/bar
+basic/l/foo/bar/baz
diff --git a/tests/bfs/O2.sh b/tests/bfs/O2.sh
new file mode 100644
index 0000000..9382456
--- /dev/null
+++ b/tests/bfs/O2.sh
@@ -0,0 +1 @@
+bfs_diff -O2 basic -not \( -type f -not -type f \)
diff --git a/tests/bfs/O3.out b/tests/bfs/O3.out
new file mode 100644
index 0000000..a7ccfe4
--- /dev/null
+++ b/tests/bfs/O3.out
@@ -0,0 +1,19 @@
+basic
+basic/a
+basic/b
+basic/c
+basic/c/d
+basic/e
+basic/e/f
+basic/g
+basic/g/h
+basic/i
+basic/j
+basic/j/foo
+basic/k
+basic/k/foo
+basic/k/foo/bar
+basic/l
+basic/l/foo
+basic/l/foo/bar
+basic/l/foo/bar/baz
diff --git a/tests/bfs/O3.sh b/tests/bfs/O3.sh
new file mode 100644
index 0000000..5bdf2bc
--- /dev/null
+++ b/tests/bfs/O3.sh
@@ -0,0 +1 @@
+bfs_diff -O3 basic -not \( -type f -not -type f \)
diff --git a/tests/bfs/O9.out b/tests/bfs/O9.out
new file mode 100644
index 0000000..a7ccfe4
--- /dev/null
+++ b/tests/bfs/O9.out
@@ -0,0 +1,19 @@
+basic
+basic/a
+basic/b
+basic/c
+basic/c/d
+basic/e
+basic/e/f
+basic/g
+basic/g/h
+basic/i
+basic/j
+basic/j/foo
+basic/k
+basic/k/foo
+basic/k/foo/bar
+basic/l
+basic/l/foo
+basic/l/foo/bar
+basic/l/foo/bar/baz
diff --git a/tests/bfs/O9.sh b/tests/bfs/O9.sh
new file mode 100644
index 0000000..c12a7a3
--- /dev/null
+++ b/tests/bfs/O9.sh
@@ -0,0 +1,4 @@
+stderr=$(invoke_bfs -warn -O9 basic 2>&1 >"$OUT")
+[ -n "$stderr" ]
+sort_output
+diff_output
diff --git a/tests/bfs/Ofast.out b/tests/bfs/Ofast.out
new file mode 100644
index 0000000..a7ccfe4
--- /dev/null
+++ b/tests/bfs/Ofast.out
@@ -0,0 +1,19 @@
+basic
+basic/a
+basic/b
+basic/c
+basic/c/d
+basic/e
+basic/e/f
+basic/g
+basic/g/h
+basic/i
+basic/j
+basic/j/foo
+basic/k
+basic/k/foo
+basic/k/foo/bar
+basic/l
+basic/l/foo
+basic/l/foo/bar
+basic/l/foo/bar/baz
diff --git a/tests/bfs/Ofast.sh b/tests/bfs/Ofast.sh
new file mode 100644
index 0000000..87c1d8d
--- /dev/null
+++ b/tests/bfs/Ofast.sh
@@ -0,0 +1 @@
+bfs_diff -Ofast basic -not \( -xtype f -not -xtype f \)
diff --git a/tests/bfs/S_bfs.out b/tests/bfs/S_bfs.out
new file mode 100644
index 0000000..bb3cd8d
--- /dev/null
+++ b/tests/bfs/S_bfs.out
@@ -0,0 +1,19 @@
+basic
+basic/a
+basic/b
+basic/c
+basic/e
+basic/g
+basic/i
+basic/j
+basic/k
+basic/l
+basic/c/d
+basic/e/f
+basic/g/h
+basic/j/foo
+basic/k/foo
+basic/l/foo
+basic/k/foo/bar
+basic/l/foo/bar
+basic/l/foo/bar/baz
diff --git a/tests/bfs/S_bfs.sh b/tests/bfs/S_bfs.sh
new file mode 100644
index 0000000..76976de
--- /dev/null
+++ b/tests/bfs/S_bfs.sh
@@ -0,0 +1,2 @@
+invoke_bfs -S bfs -s basic >"$OUT"
+diff_output
diff --git a/tests/bfs/S_dfs.out b/tests/bfs/S_dfs.out
new file mode 100644
index 0000000..a7ccfe4
--- /dev/null
+++ b/tests/bfs/S_dfs.out
@@ -0,0 +1,19 @@
+basic
+basic/a
+basic/b
+basic/c
+basic/c/d
+basic/e
+basic/e/f
+basic/g
+basic/g/h
+basic/i
+basic/j
+basic/j/foo
+basic/k
+basic/k/foo
+basic/k/foo/bar
+basic/l
+basic/l/foo
+basic/l/foo/bar
+basic/l/foo/bar/baz
diff --git a/tests/bfs/S_dfs.sh b/tests/bfs/S_dfs.sh
new file mode 100644
index 0000000..7dd7a46
--- /dev/null
+++ b/tests/bfs/S_dfs.sh
@@ -0,0 +1,2 @@
+invoke_bfs -S dfs -s basic >"$OUT"
+diff_output
diff --git a/tests/bfs/S_ids.out b/tests/bfs/S_ids.out
new file mode 100644
index 0000000..bb3cd8d
--- /dev/null
+++ b/tests/bfs/S_ids.out
@@ -0,0 +1,19 @@
+basic
+basic/a
+basic/b
+basic/c
+basic/e
+basic/g
+basic/i
+basic/j
+basic/k
+basic/l
+basic/c/d
+basic/e/f
+basic/g/h
+basic/j/foo
+basic/k/foo
+basic/l/foo
+basic/k/foo/bar
+basic/l/foo/bar
+basic/l/foo/bar/baz
diff --git a/tests/bfs/S_ids.sh b/tests/bfs/S_ids.sh
new file mode 100644
index 0000000..3995cf0
--- /dev/null
+++ b/tests/bfs/S_ids.sh
@@ -0,0 +1,2 @@
+invoke_bfs -S ids -s basic >"$OUT"
+diff_output
diff --git a/tests/bfs/and_incomplete.sh b/tests/bfs/and_incomplete.sh
new file mode 100644
index 0000000..05abc2d
--- /dev/null
+++ b/tests/bfs/and_incomplete.sh
@@ -0,0 +1 @@
+! invoke_bfs -print -a
diff --git a/tests/bfs/capable.out b/tests/bfs/capable.out
new file mode 100644
index 0000000..ac7b5ce
--- /dev/null
+++ b/tests/bfs/capable.out
@@ -0,0 +1 @@
+./capable
diff --git a/tests/bfs/capable.sh b/tests/bfs/capable.sh
new file mode 100644
index 0000000..35bb0b4
--- /dev/null
+++ b/tests/bfs/capable.sh
@@ -0,0 +1,10 @@
+test "$UNAME" = "Linux" || skip
+invoke_bfs . -quit -capable || skip
+
+cd "$TEST"
+
+"$XTOUCH" normal capable
+bfs_sudo setcap all+ep capable || skip
+ln -s capable link
+
+bfs_diff . -capable
diff --git a/tests/bfs/closed_stderr.sh b/tests/bfs/closed_stderr.sh
new file mode 100644
index 0000000..26abd85
--- /dev/null
+++ b/tests/bfs/closed_stderr.sh
@@ -0,0 +1,4 @@
+# Check if the platform automatically re-opens stderr before we can
+(bash -c 'echo >&2' 2>&-) && skip
+
+! invoke_bfs basic >&- 2>&-
diff --git a/tests/bfs/closed_stdin.out b/tests/bfs/closed_stdin.out
new file mode 100644
index 0000000..a7ccfe4
--- /dev/null
+++ b/tests/bfs/closed_stdin.out
@@ -0,0 +1,19 @@
+basic
+basic/a
+basic/b
+basic/c
+basic/c/d
+basic/e
+basic/e/f
+basic/g
+basic/g/h
+basic/i
+basic/j
+basic/j/foo
+basic/k
+basic/k/foo
+basic/k/foo/bar
+basic/l
+basic/l/foo
+basic/l/foo/bar
+basic/l/foo/bar/baz
diff --git a/tests/bfs/closed_stdin.sh b/tests/bfs/closed_stdin.sh
new file mode 100644
index 0000000..6932be8
--- /dev/null
+++ b/tests/bfs/closed_stdin.sh
@@ -0,0 +1 @@
+bfs_diff basic <&-
diff --git a/tests/bfs/closed_stdout.sh b/tests/bfs/closed_stdout.sh
new file mode 100644
index 0000000..5b6f7c3
--- /dev/null
+++ b/tests/bfs/closed_stdout.sh
@@ -0,0 +1,4 @@
+# Check if the platform automatically re-opens stdout before we can
+(bash -c echo >&-) && skip
+
+! invoke_bfs basic >&-
diff --git a/tests/bfs/color.out b/tests/bfs/color.out
new file mode 100644
index 0000000..a439814
--- /dev/null
+++ b/tests/bfs/color.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color.sh b/tests/bfs/color.sh
new file mode 100644
index 0000000..23f05a3
--- /dev/null
+++ b/tests/bfs/color.sh
@@ -0,0 +1 @@
+bfs_diff rainbow -color
diff --git a/tests/bfs/color_L.out b/tests/bfs/color_L.out
new file mode 100644
index 0000000..85923db
--- /dev/null
+++ b/tests/bfs/color_L.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/chardev_link
+rainbow/socket
+rainbow/broken
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/link.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color_L.sh b/tests/bfs/color_L.sh
new file mode 100644
index 0000000..823db62
--- /dev/null
+++ b/tests/bfs/color_L.sh
@@ -0,0 +1 @@
+bfs_diff -L rainbow -color
diff --git a/tests/bfs/color_L_ln_target.out b/tests/bfs/color_L_ln_target.out
new file mode 100644
index 0000000..23fe8d7
--- /dev/null
+++ b/tests/bfs/color_L_ln_target.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/broken
+rainbow/exec.sh
+rainbow/chardev_link
+rainbow/socket
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/link.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color_L_ln_target.sh b/tests/bfs/color_L_ln_target.sh
new file mode 100644
index 0000000..cc5991d
--- /dev/null
+++ b/tests/bfs/color_L_ln_target.sh
@@ -0,0 +1 @@
+LS_COLORS="ln=target:or=01;31:mi=01;33:" bfs_diff -L rainbow -color
diff --git a/tests/bfs/color_L_no_stat.out b/tests/bfs/color_L_no_stat.out
new file mode 100644
index 0000000..72e0319
--- /dev/null
+++ b/tests/bfs/color_L_no_stat.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/chardev_link
+rainbow/socket
+rainbow/broken
+rainbow/file.txt
+rainbow/link.txt
+rainbow/pipe
+rainbow/exec.sh
+rainbow/file.dat
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/sgid
+rainbow/sugid
+rainbow/suid
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
+rainbow/ow
+rainbow/sticky
+rainbow/sticky_ow
diff --git a/tests/bfs/color_L_no_stat.sh b/tests/bfs/color_L_no_stat.sh
new file mode 100644
index 0000000..0a2caf0
--- /dev/null
+++ b/tests/bfs/color_L_no_stat.sh
@@ -0,0 +1 @@
+LS_COLORS="mh=0:ex=0:sg=0:su=0:st=0:ow=0:tw=0:*.txt=01:" bfs_diff -L rainbow -color
diff --git a/tests/bfs/color_auto.out b/tests/bfs/color_auto.out
new file mode 100644
index 0000000..a439814
--- /dev/null
+++ b/tests/bfs/color_auto.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color_auto.sh b/tests/bfs/color_auto.sh
new file mode 100644
index 0000000..7e875cc
--- /dev/null
+++ b/tests/bfs/color_auto.sh
@@ -0,0 +1,4 @@
+unset NO_COLOR
+bfs_pty rainbow >"$OUT"
+sort_output
+diff_output
diff --git a/tests/bfs/color_cd0_no.out b/tests/bfs/color_cd0_no.out
new file mode 100644
index 0000000..37b3fbc
--- /dev/null
+++ b/tests/bfs/color_cd0_no.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/file.dat
+rainbow/file.txt
+rainbow/link.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/chardev_link
diff --git a/tests/bfs/color_cd0_no.sh b/tests/bfs/color_cd0_no.sh
new file mode 100644
index 0000000..325a782
--- /dev/null
+++ b/tests/bfs/color_cd0_no.sh
@@ -0,0 +1 @@
+LS_COLORS="ln=target:cd=0:no=01;92:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_deep.out b/tests/bfs/color_deep.out
new file mode 100644
index 0000000..fb990d5
--- /dev/null
+++ b/tests/bfs/color_deep.out
@@ -0,0 +1,16 @@
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
diff --git a/tests/bfs/color_deep.sh b/tests/bfs/color_deep.sh
new file mode 100644
index 0000000..a83ee0e
--- /dev/null
+++ b/tests/bfs/color_deep.sh
@@ -0,0 +1,7 @@
+name="0123456789ABCDEF"
+name="${name}${name}${name}${name}"
+name="${name}${name}${name}${name}"
+name="${name:0:255}"
+export LS_COLORS="*${name}=01:"
+
+bfs_diff deep -color -type f -printf '%f\n'
diff --git a/tests/bfs/color_escapes.out b/tests/bfs/color_escapes.out
new file mode 100644
index 0000000..0bf9fbb
--- /dev/null
+++ b/tests/bfs/color_escapes.out
@@ -0,0 +1,27 @@
+:$'rainbow/\e[1m'
+:$'rainbow/\e[1m/'$'\e[0m'
+:rainbow
+:rainbow/:exec.sh
+:rainbow/:socket
+:rainbow/:broken
+:rainbow/:chardev_link
+:rainbow/:link.txt
+:rainbow/:sticky_ow
+:rainbow/:sgid
+:rainbow/:pipe
+:rainbow/:ow
+:rainbow/:sugid
+:rainbow/:suid
+:rainbow/:sticky
+:rainbow/file.dat
+:rainbow/file.txt
+:rainbow/lower.gz
+:rainbow/lower.tar
+:rainbow/lower.tar.gz
+:rainbow/lu.tar.GZ
+:rainbow/mh1
+:rainbow/mh2
+:rainbow/ul.TAR.gz
+:rainbow/upper.GZ
+:rainbow/upper.TAR
+:rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color_escapes.sh b/tests/bfs/color_escapes.sh
new file mode 100644
index 0000000..eb5817f
--- /dev/null
+++ b/tests/bfs/color_escapes.sh
@@ -0,0 +1 @@
+LS_COLORS="lc=\e[:rc=\155\::ec=^[\x5B\x6d:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_ext.out b/tests/bfs/color_ext.out
new file mode 100644
index 0000000..218100f
--- /dev/null
+++ b/tests/bfs/color_ext.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/file.txt
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color_ext.sh b/tests/bfs/color_ext.sh
new file mode 100644
index 0000000..c9f6d46
--- /dev/null
+++ b/tests/bfs/color_ext.sh
@@ -0,0 +1 @@
+LS_COLORS="*.txt=01:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_ext0.out b/tests/bfs/color_ext0.out
new file mode 100644
index 0000000..d2a7fd5
--- /dev/null
+++ b/tests/bfs/color_ext0.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/file.txt
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color_ext0.sh b/tests/bfs/color_ext0.sh
new file mode 100644
index 0000000..371a9c5
--- /dev/null
+++ b/tests/bfs/color_ext0.sh
@@ -0,0 +1 @@
+LS_COLORS="*.txt=00:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_ext_case.out b/tests/bfs/color_ext_case.out
new file mode 100644
index 0000000..93dc8f6
--- /dev/null
+++ b/tests/bfs/color_ext_case.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/lower.gz
+rainbow/lower.tar.gz
+rainbow/exec.sh
+rainbow/upper.GZ
+rainbow/upper.TAR.GZ
+rainbow/lower.tar
+rainbow/upper.TAR
+rainbow/ul.TAR.gz
+rainbow/lu.tar.GZ
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/file.txt
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/mh1
+rainbow/mh2
diff --git a/tests/bfs/color_ext_case.sh b/tests/bfs/color_ext_case.sh
new file mode 100644
index 0000000..4adba69
--- /dev/null
+++ b/tests/bfs/color_ext_case.sh
@@ -0,0 +1,6 @@
+# *.gz=01;31:*.GZ=01;32 -- case sensitive
+# *.tAr=01;33:*.TaR=01;33 -- case-insensitive
+# *.TAR.gz=01;34:*.tar.GZ=01;35 -- case-sensitive
+# *.txt=35:*TXT=36 -- case-insensitive
+export LS_COLORS="*.gz=01;31:*.GZ=01;32:*.tAr=01;33:*.TaR=01;33:*.TAR.gz=01;34:*.tar.GZ=01;35:*.txt=35:*TXT=36"
+bfs_diff rainbow -color
diff --git a/tests/bfs/color_ext_override.out b/tests/bfs/color_ext_override.out
new file mode 100644
index 0000000..0acfcbc
--- /dev/null
+++ b/tests/bfs/color_ext_override.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/lower.tar
+rainbow/upper.TAR
+rainbow/lower.gz
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR.GZ
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/mh1
+rainbow/mh2
diff --git a/tests/bfs/color_ext_override.sh b/tests/bfs/color_ext_override.sh
new file mode 100644
index 0000000..ac4c7fb
--- /dev/null
+++ b/tests/bfs/color_ext_override.sh
@@ -0,0 +1 @@
+LS_COLORS="*.tar.gz=01;31:*.TAR=01;32:*.gz=01;33:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_ext_underride.out b/tests/bfs/color_ext_underride.out
new file mode 100644
index 0000000..5c98341
--- /dev/null
+++ b/tests/bfs/color_ext_underride.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/ul.TAR.gz
+rainbow/upper.TAR.GZ
+rainbow/exec.sh
+rainbow/lower.tar
+rainbow/upper.TAR
+rainbow/lower.gz
+rainbow/upper.GZ
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/mh1
+rainbow/mh2
diff --git a/tests/bfs/color_ext_underride.sh b/tests/bfs/color_ext_underride.sh
new file mode 100644
index 0000000..fb12e01
--- /dev/null
+++ b/tests/bfs/color_ext_underride.sh
@@ -0,0 +1 @@
+LS_COLORS="*.gz=01;33:*.TAR=01;32:*.tar.gz=01;31:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_fi0_no.out b/tests/bfs/color_fi0_no.out
new file mode 100644
index 0000000..a439814
--- /dev/null
+++ b/tests/bfs/color_fi0_no.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color_fi0_no.sh b/tests/bfs/color_fi0_no.sh
new file mode 100644
index 0000000..f947d64
--- /dev/null
+++ b/tests/bfs/color_fi0_no.sh
@@ -0,0 +1 @@
+LS_COLORS="fi=0:no=01;92:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_fi_no.out b/tests/bfs/color_fi_no.out
new file mode 100644
index 0000000..1c1ad8e
--- /dev/null
+++ b/tests/bfs/color_fi_no.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
diff --git a/tests/bfs/color_fi_no.sh b/tests/bfs/color_fi_no.sh
new file mode 100644
index 0000000..c2b4ec7
--- /dev/null
+++ b/tests/bfs/color_fi_no.sh
@@ -0,0 +1 @@
+LS_COLORS="fi=01;91:no=01;92:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_ln_target.out b/tests/bfs/color_ln_target.out
new file mode 100644
index 0000000..23fe8d7
--- /dev/null
+++ b/tests/bfs/color_ln_target.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/broken
+rainbow/exec.sh
+rainbow/chardev_link
+rainbow/socket
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/link.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color_ln_target.sh b/tests/bfs/color_ln_target.sh
new file mode 100644
index 0000000..707d25e
--- /dev/null
+++ b/tests/bfs/color_ln_target.sh
@@ -0,0 +1 @@
+LS_COLORS="ln=target:or=01;31:mi=01;33:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_ls.out b/tests/bfs/color_ls.out
new file mode 100644
index 0000000..f69eb9c
--- /dev/null
+++ b/tests/bfs/color_ls.out
@@ -0,0 +1,12 @@
+scratch/foo/bar
+scratch/foo/bar
+/__bfs__/nowhere
+/__bfs__/nowhere
+foo/bar/nowhere
+foo/bar/nowhere
+foo/bar/nowhere/nothing
+foo/bar/nowhere/nothing
+foo/bar/baz
+foo/bar/baz
+foo/bar/baz//qux
+foo/bar/baz//qux
diff --git a/tests/bfs/color_ls.sh b/tests/bfs/color_ls.sh
new file mode 100644
index 0000000..f1cc216
--- /dev/null
+++ b/tests/bfs/color_ls.sh
@@ -0,0 +1,15 @@
+cd "$TEST"
+"$XTOUCH" -p scratch/foo/bar/baz
+ln -s foo/bar/baz scratch/link
+ln -s foo/bar/nowhere scratch/broken
+ln -s foo/bar/nowhere/nothing scratch/nested
+ln -s foo/bar/baz//qux scratch/notdir
+ln -s scratch/foo/bar scratch/relative
+mkdir scratch/__bfs__
+ln -s /__bfs__/nowhere scratch/absolute
+
+export LS_COLORS="or=01;31:"
+invoke_bfs scratch/{,link,broken,nested,notdir,relative,absolute} -color -type l -ls \
+ | sed 's/.* -> //' \
+ | sort >"$OUT"
+diff_output
diff --git a/tests/bfs/color_mh.out b/tests/bfs/color_mh.out
new file mode 100644
index 0000000..c658082
--- /dev/null
+++ b/tests/bfs/color_mh.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/mh1
+rainbow/mh2
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color_mh.sh b/tests/bfs/color_mh.sh
new file mode 100644
index 0000000..aff1845
--- /dev/null
+++ b/tests/bfs/color_mh.sh
@@ -0,0 +1 @@
+LS_COLORS="mh=01:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_mh0.out b/tests/bfs/color_mh0.out
new file mode 100644
index 0000000..a439814
--- /dev/null
+++ b/tests/bfs/color_mh0.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color_mh0.sh b/tests/bfs/color_mh0.sh
new file mode 100644
index 0000000..7de880d
--- /dev/null
+++ b/tests/bfs/color_mh0.sh
@@ -0,0 +1 @@
+LS_COLORS="mh=00:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_mi.out b/tests/bfs/color_mi.out
new file mode 100644
index 0000000..a439814
--- /dev/null
+++ b/tests/bfs/color_mi.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color_mi.sh b/tests/bfs/color_mi.sh
new file mode 100644
index 0000000..06dd8c6
--- /dev/null
+++ b/tests/bfs/color_mi.sh
@@ -0,0 +1 @@
+LS_COLORS="mi=01:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_missing_colon.out b/tests/bfs/color_missing_colon.out
new file mode 100644
index 0000000..218100f
--- /dev/null
+++ b/tests/bfs/color_missing_colon.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/file.txt
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color_missing_colon.sh b/tests/bfs/color_missing_colon.sh
new file mode 100644
index 0000000..afa3763
--- /dev/null
+++ b/tests/bfs/color_missing_colon.sh
@@ -0,0 +1 @@
+LS_COLORS="*.txt=01" bfs_diff rainbow -color
diff --git a/tests/bfs/color_no.out b/tests/bfs/color_no.out
new file mode 100644
index 0000000..67e1eee
--- /dev/null
+++ b/tests/bfs/color_no.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
diff --git a/tests/bfs/color_no.sh b/tests/bfs/color_no.sh
new file mode 100644
index 0000000..b7527cb
--- /dev/null
+++ b/tests/bfs/color_no.sh
@@ -0,0 +1 @@
+LS_COLORS="no=01;92:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_no_stat.out b/tests/bfs/color_no_stat.out
new file mode 100644
index 0000000..e3031b2
--- /dev/null
+++ b/tests/bfs/color_no_stat.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/file.txt
+rainbow/pipe
+rainbow/exec.sh
+rainbow/file.dat
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/sgid
+rainbow/sugid
+rainbow/suid
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
+rainbow/ow
+rainbow/sticky
+rainbow/sticky_ow
diff --git a/tests/bfs/color_no_stat.sh b/tests/bfs/color_no_stat.sh
new file mode 100644
index 0000000..0bc2520
--- /dev/null
+++ b/tests/bfs/color_no_stat.sh
@@ -0,0 +1 @@
+LS_COLORS="mh=0:ex=0:sg=0:su=0:st=0:ow=0:tw=0:*.txt=01:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_nul.out b/tests/bfs/color_nul.out
new file mode 100644
index 0000000..8ccd9a7
--- /dev/null
+++ b/tests/bfs/color_nul.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/lower.gz
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR.GZ
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.tar
+rainbow/mh1
+rainbow/mh2
+rainbow/upper.TAR
diff --git a/tests/bfs/color_nul.sh b/tests/bfs/color_nul.sh
new file mode 100644
index 0000000..cb662d6
--- /dev/null
+++ b/tests/bfs/color_nul.sh
@@ -0,0 +1,3 @@
+LS_COLORS="ec=\33[\0m:*.gz=\0\61;31:" invoke_bfs rainbow -color | tr '\0' '0' >"$OUT"
+sort_output
+diff_output
diff --git a/tests/bfs/color_or.out b/tests/bfs/color_or.out
new file mode 100644
index 0000000..0bd2570
--- /dev/null
+++ b/tests/bfs/color_or.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/broken
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color_or.sh b/tests/bfs/color_or.sh
new file mode 100644
index 0000000..bccb400
--- /dev/null
+++ b/tests/bfs/color_or.sh
@@ -0,0 +1 @@
+LS_COLORS="or=01:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_or0_mi.out b/tests/bfs/color_or0_mi.out
new file mode 100644
index 0000000..a439814
--- /dev/null
+++ b/tests/bfs/color_or0_mi.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color_or0_mi.sh b/tests/bfs/color_or0_mi.sh
new file mode 100644
index 0000000..a362cf1
--- /dev/null
+++ b/tests/bfs/color_or0_mi.sh
@@ -0,0 +1 @@
+LS_COLORS="or=00:mi=01;33:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_or0_mi0.out b/tests/bfs/color_or0_mi0.out
new file mode 100644
index 0000000..a439814
--- /dev/null
+++ b/tests/bfs/color_or0_mi0.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color_or0_mi0.sh b/tests/bfs/color_or0_mi0.sh
new file mode 100644
index 0000000..d7c00f6
--- /dev/null
+++ b/tests/bfs/color_or0_mi0.sh
@@ -0,0 +1 @@
+LS_COLORS="or=00:mi=00:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_or_mi.out b/tests/bfs/color_or_mi.out
new file mode 100644
index 0000000..fb67e58
--- /dev/null
+++ b/tests/bfs/color_or_mi.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/broken
+rainbow/exec.sh
+rainbow/socket
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color_or_mi.sh b/tests/bfs/color_or_mi.sh
new file mode 100644
index 0000000..467ce6b
--- /dev/null
+++ b/tests/bfs/color_or_mi.sh
@@ -0,0 +1 @@
+LS_COLORS="or=01;31:mi=01;33:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_or_mi0.out b/tests/bfs/color_or_mi0.out
new file mode 100644
index 0000000..fb67e58
--- /dev/null
+++ b/tests/bfs/color_or_mi0.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/broken
+rainbow/exec.sh
+rainbow/socket
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color_or_mi0.sh b/tests/bfs/color_or_mi0.sh
new file mode 100644
index 0000000..a9c36bf
--- /dev/null
+++ b/tests/bfs/color_or_mi0.sh
@@ -0,0 +1 @@
+LS_COLORS="or=01;31:mi=00:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_rs_lc_rc_ec.out b/tests/bfs/color_rs_lc_rc_ec.out
new file mode 100644
index 0000000..077ef8d
--- /dev/null
+++ b/tests/bfs/color_rs_lc_rc_ec.out
@@ -0,0 +1,27 @@
+LC01;34RC$'rainbow/\e[1m'EC
+LC01;34RC$'rainbow/\e[1m/'EC$'\e[0m'
+LC01;34RCrainbow/ECLC01;32RCexec.shEC
+LC01;34RCrainbow/ECLC01;35RCsocketEC
+LC01;34RCrainbow/ECLC01;36RCbrokenEC
+LC01;34RCrainbow/ECLC01;36RCchardev_linkEC
+LC01;34RCrainbow/ECLC01;36RClink.txtEC
+LC01;34RCrainbow/ECLC30;42RCsticky_owEC
+LC01;34RCrainbow/ECLC30;43RCsgidEC
+LC01;34RCrainbow/ECLC33RCpipeEC
+LC01;34RCrainbow/ECLC34;42RCowEC
+LC01;34RCrainbow/ECLC37;41RCsugidEC
+LC01;34RCrainbow/ECLC37;41RCsuidEC
+LC01;34RCrainbow/ECLC37;44RCstickyEC
+LC01;34RCrainbow/ECfile.dat
+LC01;34RCrainbow/ECfile.txt
+LC01;34RCrainbow/EClower.gz
+LC01;34RCrainbow/EClower.tar
+LC01;34RCrainbow/EClower.tar.gz
+LC01;34RCrainbow/EClu.tar.GZ
+LC01;34RCrainbow/ECmh1
+LC01;34RCrainbow/ECmh2
+LC01;34RCrainbow/ECul.TAR.gz
+LC01;34RCrainbow/ECupper.GZ
+LC01;34RCrainbow/ECupper.TAR
+LC01;34RCrainbow/ECupper.TAR.GZ
+LC01;34RCrainbowEC
diff --git a/tests/bfs/color_rs_lc_rc_ec.sh b/tests/bfs/color_rs_lc_rc_ec.sh
new file mode 100644
index 0000000..467b2da
--- /dev/null
+++ b/tests/bfs/color_rs_lc_rc_ec.sh
@@ -0,0 +1 @@
+LS_COLORS="rs=RS:lc=LC:rc=RC:ec=EC:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_st0_tw0_ow.out b/tests/bfs/color_st0_tw0_ow.out
new file mode 100644
index 0000000..a82762b
--- /dev/null
+++ b/tests/bfs/color_st0_tw0_ow.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sticky_ow
+rainbow/sugid
+rainbow/suid
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
+rainbow/sticky
diff --git a/tests/bfs/color_st0_tw0_ow.sh b/tests/bfs/color_st0_tw0_ow.sh
new file mode 100644
index 0000000..8e2b8e3
--- /dev/null
+++ b/tests/bfs/color_st0_tw0_ow.sh
@@ -0,0 +1 @@
+LS_COLORS="st=00:tw=00:ow=34;42:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_st0_tw0_ow0.out b/tests/bfs/color_st0_tw0_ow0.out
new file mode 100644
index 0000000..041f1d4
--- /dev/null
+++ b/tests/bfs/color_st0_tw0_ow0.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sgid
+rainbow/pipe
+rainbow/sugid
+rainbow/suid
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
+rainbow/ow
+rainbow/sticky
+rainbow/sticky_ow
diff --git a/tests/bfs/color_st0_tw0_ow0.sh b/tests/bfs/color_st0_tw0_ow0.sh
new file mode 100644
index 0000000..c5d5fe7
--- /dev/null
+++ b/tests/bfs/color_st0_tw0_ow0.sh
@@ -0,0 +1 @@
+LS_COLORS="st=00:tw=00:ow=00:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_st0_tw_ow.out b/tests/bfs/color_st0_tw_ow.out
new file mode 100644
index 0000000..4dcb2f2
--- /dev/null
+++ b/tests/bfs/color_st0_tw_ow.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky_ow
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
+rainbow/sticky
diff --git a/tests/bfs/color_st0_tw_ow.sh b/tests/bfs/color_st0_tw_ow.sh
new file mode 100644
index 0000000..8fd9605
--- /dev/null
+++ b/tests/bfs/color_st0_tw_ow.sh
@@ -0,0 +1 @@
+LS_COLORS="st=00:tw=40;32:ow=34;42:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_st0_tw_ow0.out b/tests/bfs/color_st0_tw_ow0.out
new file mode 100644
index 0000000..954ce9c
--- /dev/null
+++ b/tests/bfs/color_st0_tw_ow0.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sgid
+rainbow/pipe
+rainbow/sugid
+rainbow/suid
+rainbow/sticky_ow
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
+rainbow/ow
+rainbow/sticky
diff --git a/tests/bfs/color_st0_tw_ow0.sh b/tests/bfs/color_st0_tw_ow0.sh
new file mode 100644
index 0000000..68c63dc
--- /dev/null
+++ b/tests/bfs/color_st0_tw_ow0.sh
@@ -0,0 +1 @@
+LS_COLORS="st=00:tw=40;32:ow=00:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_st_tw0_ow.out b/tests/bfs/color_st_tw0_ow.out
new file mode 100644
index 0000000..a6e9a16
--- /dev/null
+++ b/tests/bfs/color_st_tw0_ow.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sticky_ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color_st_tw0_ow.sh b/tests/bfs/color_st_tw0_ow.sh
new file mode 100644
index 0000000..be16251
--- /dev/null
+++ b/tests/bfs/color_st_tw0_ow.sh
@@ -0,0 +1 @@
+LS_COLORS="st=37;44:tw=00:ow=34;42:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_st_tw0_ow0.out b/tests/bfs/color_st_tw0_ow0.out
new file mode 100644
index 0000000..756dafb
--- /dev/null
+++ b/tests/bfs/color_st_tw0_ow0.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sgid
+rainbow/pipe
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/sticky_ow
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
+rainbow/ow
diff --git a/tests/bfs/color_st_tw0_ow0.sh b/tests/bfs/color_st_tw0_ow0.sh
new file mode 100644
index 0000000..f869e7c
--- /dev/null
+++ b/tests/bfs/color_st_tw0_ow0.sh
@@ -0,0 +1 @@
+LS_COLORS="st=37;44:tw=00:ow=00:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_st_tw_ow0.out b/tests/bfs/color_st_tw_ow0.out
new file mode 100644
index 0000000..6e4a260
--- /dev/null
+++ b/tests/bfs/color_st_tw_ow0.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sgid
+rainbow/pipe
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/sticky_ow
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
+rainbow/ow
diff --git a/tests/bfs/color_st_tw_ow0.sh b/tests/bfs/color_st_tw_ow0.sh
new file mode 100644
index 0000000..99a17a6
--- /dev/null
+++ b/tests/bfs/color_st_tw_ow0.sh
@@ -0,0 +1 @@
+LS_COLORS="st=37;44:tw=40;32:ow=00:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_star.sh b/tests/bfs/color_star.sh
new file mode 100644
index 0000000..6d5312e
--- /dev/null
+++ b/tests/bfs/color_star.sh
@@ -0,0 +1,2 @@
+# Regression test: don't segfault on LS_COLORS="*"
+! LS_COLORS="*" invoke_bfs rainbow -color
diff --git a/tests/bfs/color_su0_sg.out b/tests/bfs/color_su0_sg.out
new file mode 100644
index 0000000..d13b6b6
--- /dev/null
+++ b/tests/bfs/color_su0_sg.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/sugid
+rainbow/pipe
+rainbow/ow
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/suid
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color_su0_sg.sh b/tests/bfs/color_su0_sg.sh
new file mode 100644
index 0000000..f5f57b4
--- /dev/null
+++ b/tests/bfs/color_su0_sg.sh
@@ -0,0 +1 @@
+LS_COLORS="su=00:sg=30;43:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_su0_sg0.out b/tests/bfs/color_su0_sg0.out
new file mode 100644
index 0000000..77fba58
--- /dev/null
+++ b/tests/bfs/color_su0_sg0.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sticky_ow
+rainbow/pipe
+rainbow/ow
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/sgid
+rainbow/sugid
+rainbow/suid
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color_su0_sg0.sh b/tests/bfs/color_su0_sg0.sh
new file mode 100644
index 0000000..0198383
--- /dev/null
+++ b/tests/bfs/color_su0_sg0.sh
@@ -0,0 +1 @@
+LS_COLORS="su=00:sg=00:" bfs_diff rainbow -color
diff --git a/tests/bfs/color_su_sg0.out b/tests/bfs/color_su_sg0.out
new file mode 100644
index 0000000..8fab046
--- /dev/null
+++ b/tests/bfs/color_su_sg0.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sticky_ow
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/sgid
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color_su_sg0.sh b/tests/bfs/color_su_sg0.sh
new file mode 100644
index 0000000..8dc6984
--- /dev/null
+++ b/tests/bfs/color_su_sg0.sh
@@ -0,0 +1 @@
+LS_COLORS="su=37;41:sg=00:" bfs_diff rainbow -color
diff --git a/tests/bfs/comma_incomplete.sh b/tests/bfs/comma_incomplete.sh
new file mode 100644
index 0000000..bd60168
--- /dev/null
+++ b/tests/bfs/comma_incomplete.sh
@@ -0,0 +1 @@
+! invoke_bfs -print ,
diff --git a/tests/bfs/data_flow_hidden.out b/tests/bfs/data_flow_hidden.out
new file mode 100644
index 0000000..a7ccfe4
--- /dev/null
+++ b/tests/bfs/data_flow_hidden.out
@@ -0,0 +1,19 @@
+basic
+basic/a
+basic/b
+basic/c
+basic/c/d
+basic/e
+basic/e/f
+basic/g
+basic/g/h
+basic/i
+basic/j
+basic/j/foo
+basic/k
+basic/k/foo
+basic/k/foo/bar
+basic/l
+basic/l/foo
+basic/l/foo/bar
+basic/l/foo/bar/baz
diff --git a/tests/bfs/data_flow_hidden.sh b/tests/bfs/data_flow_hidden.sh
new file mode 100644
index 0000000..6afaab2
--- /dev/null
+++ b/tests/bfs/data_flow_hidden.sh
@@ -0,0 +1 @@
+bfs_diff basic \( -hidden -not -hidden \) -o \( -hidden -o -not -hidden \)
diff --git a/tests/bfs/deep_strict.out b/tests/bfs/deep_strict.out
new file mode 100644
index 0000000..c385fce
--- /dev/null
+++ b/tests/bfs/deep_strict.out
@@ -0,0 +1,16 @@
+deep/0/.../0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE (4358)
+deep/1/.../0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE (4358)
+deep/2/.../0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE (4358)
+deep/3/.../0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE (4358)
+deep/4/.../0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE (4358)
+deep/5/.../0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE (4358)
+deep/6/.../0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE (4358)
+deep/7/.../0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE (4358)
+deep/8/.../0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE (4358)
+deep/9/.../0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE (4358)
+deep/A/.../0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE (4358)
+deep/B/.../0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE (4358)
+deep/C/.../0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE (4358)
+deep/D/.../0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE (4358)
+deep/E/.../0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE (4358)
+deep/F/.../0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE (4358)
diff --git a/tests/bfs/deep_strict.sh b/tests/bfs/deep_strict.sh
new file mode 100644
index 0000000..22453c0
--- /dev/null
+++ b/tests/bfs/deep_strict.sh
@@ -0,0 +1,3 @@
+# Not even enough fds to keep the root open
+ulimit -n $((NOPENFD + 4))
+bfs_diff deep -type f -exec bash -c 'echo "${1:0:6}/.../${1##*/} (${#1})"' bash {} \;
diff --git a/tests/bfs/exclude_depth.out b/tests/bfs/exclude_depth.out
new file mode 100644
index 0000000..59e3c42
--- /dev/null
+++ b/tests/bfs/exclude_depth.out
@@ -0,0 +1,13 @@
+basic
+basic/a
+basic/b
+basic/c
+basic/c/d
+basic/e
+basic/e/f
+basic/g
+basic/g/h
+basic/i
+basic/j
+basic/k
+basic/l
diff --git a/tests/bfs/exclude_depth.sh b/tests/bfs/exclude_depth.sh
new file mode 100644
index 0000000..437b4dd
--- /dev/null
+++ b/tests/bfs/exclude_depth.sh
@@ -0,0 +1 @@
+bfs_diff basic -depth -exclude -name foo
diff --git a/tests/bfs/exclude_exclude.sh b/tests/bfs/exclude_exclude.sh
new file mode 100644
index 0000000..739342f
--- /dev/null
+++ b/tests/bfs/exclude_exclude.sh
@@ -0,0 +1 @@
+! invoke_bfs basic -exclude -exclude -name foo
diff --git a/tests/bfs/exclude_mindepth.out b/tests/bfs/exclude_mindepth.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/bfs/exclude_mindepth.out
diff --git a/tests/bfs/exclude_mindepth.sh b/tests/bfs/exclude_mindepth.sh
new file mode 100644
index 0000000..c8f70f9
--- /dev/null
+++ b/tests/bfs/exclude_mindepth.sh
@@ -0,0 +1 @@
+bfs_diff basic -mindepth 3 -exclude -name foo
diff --git a/tests/bfs/exclude_name.out b/tests/bfs/exclude_name.out
new file mode 100644
index 0000000..59e3c42
--- /dev/null
+++ b/tests/bfs/exclude_name.out
@@ -0,0 +1,13 @@
+basic
+basic/a
+basic/b
+basic/c
+basic/c/d
+basic/e
+basic/e/f
+basic/g
+basic/g/h
+basic/i
+basic/j
+basic/k
+basic/l
diff --git a/tests/bfs/exclude_name.sh b/tests/bfs/exclude_name.sh
new file mode 100644
index 0000000..7cf9f33
--- /dev/null
+++ b/tests/bfs/exclude_name.sh
@@ -0,0 +1 @@
+bfs_diff basic -exclude -name foo
diff --git a/tests/bfs/exclude_print.sh b/tests/bfs/exclude_print.sh
new file mode 100644
index 0000000..dc89e1d
--- /dev/null
+++ b/tests/bfs/exclude_print.sh
@@ -0,0 +1 @@
+! invoke_bfs basic -exclude -print
diff --git a/tests/bfs/exec_flush_fprint.out b/tests/bfs/exec_flush_fprint.out
new file mode 100644
index 0000000..511198f
--- /dev/null
+++ b/tests/bfs/exec_flush_fprint.out
@@ -0,0 +1 @@
+basic/a
diff --git a/tests/bfs/exec_flush_fprint.sh b/tests/bfs/exec_flush_fprint.sh
new file mode 100644
index 0000000..a862773
--- /dev/null
+++ b/tests/bfs/exec_flush_fprint.sh
@@ -0,0 +1,2 @@
+# Even non-stdstreams should be flushed
+bfs_diff basic/a -fprint "$OUT.f" -exec cat "$OUT.f" \;
diff --git a/tests/bfs/exec_flush_fprint_fail.sh b/tests/bfs/exec_flush_fprint_fail.sh
new file mode 100644
index 0000000..cd38e41
--- /dev/null
+++ b/tests/bfs/exec_flush_fprint_fail.sh
@@ -0,0 +1,2 @@
+test -e /dev/full || skip
+! invoke_bfs basic/a -fprint /dev/full -exec true \;
diff --git a/tests/bfs/execdir_plus.out b/tests/bfs/execdir_plus.out
new file mode 100644
index 0000000..8866a8f
--- /dev/null
+++ b/tests/bfs/execdir_plus.out
@@ -0,0 +1,11 @@
+./a ./b ./c ./e ./g ./i ./j ./k ./l
+./bar
+./bar
+./basic
+./baz
+./d
+./f
+./foo
+./foo
+./foo
+./h
diff --git a/tests/bfs/execdir_plus.sh b/tests/bfs/execdir_plus.sh
new file mode 100644
index 0000000..6f24bdc
--- /dev/null
+++ b/tests/bfs/execdir_plus.sh
@@ -0,0 +1,4 @@
+tree=$(invoke_bfs -D tree 2>&1 -quit)
+[[ "$tree" == *"-S dfs"* ]] && skip
+
+bfs_diff -j1 basic -execdir "$TESTS/sort-args.sh" {} +
diff --git a/tests/bfs/execdir_plus_nonexistent.out b/tests/bfs/execdir_plus_nonexistent.out
new file mode 100644
index 0000000..a7ccfe4
--- /dev/null
+++ b/tests/bfs/execdir_plus_nonexistent.out
@@ -0,0 +1,19 @@
+basic
+basic/a
+basic/b
+basic/c
+basic/c/d
+basic/e
+basic/e/f
+basic/g
+basic/g/h
+basic/i
+basic/j
+basic/j/foo
+basic/k
+basic/k/foo
+basic/k/foo/bar
+basic/l
+basic/l/foo
+basic/l/foo/bar
+basic/l/foo/bar/baz
diff --git a/tests/bfs/execdir_plus_nonexistent.sh b/tests/bfs/execdir_plus_nonexistent.sh
new file mode 100644
index 0000000..ed7ed56
--- /dev/null
+++ b/tests/bfs/execdir_plus_nonexistent.sh
@@ -0,0 +1,2 @@
+bfs_diff basic -execdir "$TESTS/nonexistent" {} + -print 2>"$TEST/err" && fail
+test -s "$TEST/err"
diff --git a/tests/bfs/expr_flag_path.out b/tests/bfs/expr_flag_path.out
new file mode 100644
index 0000000..e67f10b
--- /dev/null
+++ b/tests/bfs/expr_flag_path.out
@@ -0,0 +1,2 @@
+links/skip/broken
+links/skip/link
diff --git a/tests/bfs/expr_flag_path.sh b/tests/bfs/expr_flag_path.sh
new file mode 100644
index 0000000..bb89d92
--- /dev/null
+++ b/tests/bfs/expr_flag_path.sh
@@ -0,0 +1 @@
+bfs_diff -type l -H links/skip
diff --git a/tests/bfs/expr_path_flag.out b/tests/bfs/expr_path_flag.out
new file mode 100644
index 0000000..e67f10b
--- /dev/null
+++ b/tests/bfs/expr_path_flag.out
@@ -0,0 +1,2 @@
+links/skip/broken
+links/skip/link
diff --git a/tests/bfs/expr_path_flag.sh b/tests/bfs/expr_path_flag.sh
new file mode 100644
index 0000000..818e5d1
--- /dev/null
+++ b/tests/bfs/expr_path_flag.sh
@@ -0,0 +1 @@
+bfs_diff -type l links/skip -H
diff --git a/tests/bfs/flag_expr_path.out b/tests/bfs/flag_expr_path.out
new file mode 100644
index 0000000..e67f10b
--- /dev/null
+++ b/tests/bfs/flag_expr_path.out
@@ -0,0 +1,2 @@
+links/skip/broken
+links/skip/link
diff --git a/tests/bfs/flag_expr_path.sh b/tests/bfs/flag_expr_path.sh
new file mode 100644
index 0000000..a414e10
--- /dev/null
+++ b/tests/bfs/flag_expr_path.sh
@@ -0,0 +1 @@
+bfs_diff -H -type l links/skip
diff --git a/tests/bfs/fprint_duplicate_stdout.out b/tests/bfs/fprint_duplicate_stdout.out
new file mode 100644
index 0000000..6c21751
--- /dev/null
+++ b/tests/bfs/fprint_duplicate_stdout.out
@@ -0,0 +1,38 @@
+basic
+basic
+basic/a
+basic/a
+basic/b
+basic/b
+basic/c
+basic/c
+basic/c/d
+basic/c/d
+basic/e
+basic/e
+basic/e/f
+basic/e/f
+basic/g
+basic/g
+basic/g/h
+basic/g/h
+basic/i
+basic/i
+basic/j
+basic/j
+basic/j/foo
+basic/j/foo
+basic/k
+basic/k
+basic/k/foo
+basic/k/foo
+basic/k/foo/bar
+basic/k/foo/bar
+basic/l
+basic/l
+basic/l/foo
+basic/l/foo
+basic/l/foo/bar
+basic/l/foo/bar
+basic/l/foo/bar/baz
+basic/l/foo/bar/baz
diff --git a/tests/bfs/fprint_duplicate_stdout.sh b/tests/bfs/fprint_duplicate_stdout.sh
new file mode 100644
index 0000000..4e95e30
--- /dev/null
+++ b/tests/bfs/fprint_duplicate_stdout.sh
@@ -0,0 +1,3 @@
+invoke_bfs basic -fprint "$OUT" -print >"$OUT"
+sort_output
+diff_output
diff --git a/tests/bfs/fprint_error_stderr.sh b/tests/bfs/fprint_error_stderr.sh
new file mode 100644
index 0000000..2cc4037
--- /dev/null
+++ b/tests/bfs/fprint_error_stderr.sh
@@ -0,0 +1,2 @@
+test -e /dev/full || skip
+! invoke_bfs basic -maxdepth 0 -fprint /dev/full 2>/dev/full
diff --git a/tests/bfs/fprint_error_stdout.sh b/tests/bfs/fprint_error_stdout.sh
new file mode 100644
index 0000000..42a7b36
--- /dev/null
+++ b/tests/bfs/fprint_error_stdout.sh
@@ -0,0 +1,2 @@
+test -e /dev/full || skip
+! invoke_bfs basic -maxdepth 0 -fprint /dev/full >/dev/full
diff --git a/tests/bfs/help.sh b/tests/bfs/help.sh
new file mode 100644
index 0000000..5029c7e
--- /dev/null
+++ b/tests/bfs/help.sh
@@ -0,0 +1,4 @@
+! invoke_bfs -help | grep -E '\{...?\}' || fail
+! invoke_bfs -D help | grep -E '\{...?\}' || fail
+! invoke_bfs -S help | grep -E '\{...?\}' || fail
+! invoke_bfs -regextype help | grep -E '\{...?\}' || fail
diff --git a/tests/bfs/hidden.out b/tests/bfs/hidden.out
new file mode 100644
index 0000000..e65ede9
--- /dev/null
+++ b/tests/bfs/hidden.out
@@ -0,0 +1 @@
+weirdnames/...
diff --git a/tests/bfs/hidden.sh b/tests/bfs/hidden.sh
new file mode 100644
index 0000000..b0413c5
--- /dev/null
+++ b/tests/bfs/hidden.sh
@@ -0,0 +1 @@
+bfs_diff weirdnames -hidden
diff --git a/tests/bfs/hidden_root.out b/tests/bfs/hidden_root.out
new file mode 100644
index 0000000..8c1371b
--- /dev/null
+++ b/tests/bfs/hidden_root.out
@@ -0,0 +1,5 @@
+...
+.../../...
+./...
+./...
+././...
diff --git a/tests/bfs/hidden_root.sh b/tests/bfs/hidden_root.sh
new file mode 100644
index 0000000..905c5b5
--- /dev/null
+++ b/tests/bfs/hidden_root.sh
@@ -0,0 +1,2 @@
+cd weirdnames
+bfs_diff . ./. ... ./... .../.. -hidden
diff --git a/tests/bfs/high_byte.sh b/tests/bfs/high_byte.sh
new file mode 100644
index 0000000..c76199f
--- /dev/null
+++ b/tests/bfs/high_byte.sh
@@ -0,0 +1 @@
+! invoke_bfs -$'\xFF'
diff --git a/tests/bfs/j0.sh b/tests/bfs/j0.sh
new file mode 100644
index 0000000..97a7c5c
--- /dev/null
+++ b/tests/bfs/j0.sh
@@ -0,0 +1 @@
+! invoke_bfs -j0 basic
diff --git a/tests/bfs/j1.out b/tests/bfs/j1.out
new file mode 100644
index 0000000..a7ccfe4
--- /dev/null
+++ b/tests/bfs/j1.out
@@ -0,0 +1,19 @@
+basic
+basic/a
+basic/b
+basic/c
+basic/c/d
+basic/e
+basic/e/f
+basic/g
+basic/g/h
+basic/i
+basic/j
+basic/j/foo
+basic/k
+basic/k/foo
+basic/k/foo/bar
+basic/l
+basic/l/foo
+basic/l/foo/bar
+basic/l/foo/bar/baz
diff --git a/tests/bfs/j1.sh b/tests/bfs/j1.sh
new file mode 100644
index 0000000..972ac1b
--- /dev/null
+++ b/tests/bfs/j1.sh
@@ -0,0 +1 @@
+bfs_diff -j1 basic
diff --git a/tests/bfs/j64.out b/tests/bfs/j64.out
new file mode 100644
index 0000000..a7ccfe4
--- /dev/null
+++ b/tests/bfs/j64.out
@@ -0,0 +1,19 @@
+basic
+basic/a
+basic/b
+basic/c
+basic/c/d
+basic/e
+basic/e/f
+basic/g
+basic/g/h
+basic/i
+basic/j
+basic/j/foo
+basic/k
+basic/k/foo
+basic/k/foo/bar
+basic/l
+basic/l/foo
+basic/l/foo/bar
+basic/l/foo/bar/baz
diff --git a/tests/bfs/j64.sh b/tests/bfs/j64.sh
new file mode 100644
index 0000000..c56788f
--- /dev/null
+++ b/tests/bfs/j64.sh
@@ -0,0 +1 @@
+bfs_diff -j64 basic
diff --git a/tests/bfs/j_negative.sh b/tests/bfs/j_negative.sh
new file mode 100644
index 0000000..809c98c
--- /dev/null
+++ b/tests/bfs/j_negative.sh
@@ -0,0 +1 @@
+! invoke_bfs -j-1 basic
diff --git a/tests/bfs/limit.out b/tests/bfs/limit.out
new file mode 100644
index 0000000..ea94276
--- /dev/null
+++ b/tests/bfs/limit.out
@@ -0,0 +1,4 @@
+basic/a
+basic/b
+basic/c/d
+basic/e/f
diff --git a/tests/bfs/limit.sh b/tests/bfs/limit.sh
new file mode 100644
index 0000000..84b605f
--- /dev/null
+++ b/tests/bfs/limit.sh
@@ -0,0 +1 @@
+bfs_diff -s basic -type f -print -limit 4
diff --git a/tests/bfs/limit_0.sh b/tests/bfs/limit_0.sh
new file mode 100644
index 0000000..3ce26de
--- /dev/null
+++ b/tests/bfs/limit_0.sh
@@ -0,0 +1 @@
+! invoke_bfs basic -print -limit 0
diff --git a/tests/bfs/limit_implicit_print.sh b/tests/bfs/limit_implicit_print.sh
new file mode 100644
index 0000000..cdb059d
--- /dev/null
+++ b/tests/bfs/limit_implicit_print.sh
@@ -0,0 +1 @@
+! invoke_bfs basic -type f -limit 1
diff --git a/tests/bfs/limit_incomplete.sh b/tests/bfs/limit_incomplete.sh
new file mode 100644
index 0000000..2d1e842
--- /dev/null
+++ b/tests/bfs/limit_incomplete.sh
@@ -0,0 +1 @@
+! invoke_bfs basic -print -limit
diff --git a/tests/bfs/limit_one.sh b/tests/bfs/limit_one.sh
new file mode 100644
index 0000000..3f8181c
--- /dev/null
+++ b/tests/bfs/limit_one.sh
@@ -0,0 +1 @@
+! invoke_bfs basic -print -limit one
diff --git a/tests/bfs/links_empty.sh b/tests/bfs/links_empty.sh
new file mode 100644
index 0000000..42cf6e5
--- /dev/null
+++ b/tests/bfs/links_empty.sh
@@ -0,0 +1 @@
+! invoke_bfs links -links ''
diff --git a/tests/bfs/links_invalid.sh b/tests/bfs/links_invalid.sh
new file mode 100644
index 0000000..4d139c9
--- /dev/null
+++ b/tests/bfs/links_invalid.sh
@@ -0,0 +1 @@
+! invoke_bfs links -links ASDF
diff --git a/tests/bfs/links_leading_space.sh b/tests/bfs/links_leading_space.sh
new file mode 100644
index 0000000..15957af
--- /dev/null
+++ b/tests/bfs/links_leading_space.sh
@@ -0,0 +1 @@
+! invoke_bfs links -links ' 1'
diff --git a/tests/bfs/links_negative.sh b/tests/bfs/links_negative.sh
new file mode 100644
index 0000000..e664b99
--- /dev/null
+++ b/tests/bfs/links_negative.sh
@@ -0,0 +1 @@
+! invoke_bfs links -links +-1
diff --git a/tests/bfs/links_noarg.sh b/tests/bfs/links_noarg.sh
new file mode 100644
index 0000000..5c948dc
--- /dev/null
+++ b/tests/bfs/links_noarg.sh
@@ -0,0 +1 @@
+! invoke_bfs links -links
diff --git a/tests/bfs/newerma_nonexistent.sh b/tests/bfs/newerma_nonexistent.sh
new file mode 100644
index 0000000..cdedb4a
--- /dev/null
+++ b/tests/bfs/newerma_nonexistent.sh
@@ -0,0 +1 @@
+! invoke_bfs times -newerma basic/nonexistent
diff --git a/tests/bfs/newermq.sh b/tests/bfs/newermq.sh
new file mode 100644
index 0000000..2f705dc
--- /dev/null
+++ b/tests/bfs/newermq.sh
@@ -0,0 +1 @@
+! invoke_bfs times -newermq times/a
diff --git a/tests/bfs/newermt_invalid.sh b/tests/bfs/newermt_invalid.sh
new file mode 100644
index 0000000..98efece
--- /dev/null
+++ b/tests/bfs/newermt_invalid.sh
@@ -0,0 +1 @@
+! invoke_bfs times -newermt not_a_date_time
diff --git a/tests/bfs/newerqm.sh b/tests/bfs/newerqm.sh
new file mode 100644
index 0000000..c0cff98
--- /dev/null
+++ b/tests/bfs/newerqm.sh
@@ -0,0 +1 @@
+! invoke_bfs times -newerqm times/a
diff --git a/tests/bfs/nocolor.out b/tests/bfs/nocolor.out
new file mode 100644
index 0000000..d51d24d
--- /dev/null
+++ b/tests/bfs/nocolor.out
@@ -0,0 +1,27 @@
+rainbow
+rainbow/
+rainbow//
+rainbow/broken
+rainbow/chardev_link
+rainbow/exec.sh
+rainbow/file.dat
+rainbow/file.txt
+rainbow/link.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ow
+rainbow/pipe
+rainbow/sgid
+rainbow/socket
+rainbow/sticky
+rainbow/sticky_ow
+rainbow/sugid
+rainbow/suid
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/nocolor.sh b/tests/bfs/nocolor.sh
new file mode 100644
index 0000000..8dace0b
--- /dev/null
+++ b/tests/bfs/nocolor.sh
@@ -0,0 +1 @@
+bfs_diff rainbow -nocolor
diff --git a/tests/bfs/nocolor_env.out b/tests/bfs/nocolor_env.out
new file mode 100644
index 0000000..d51d24d
--- /dev/null
+++ b/tests/bfs/nocolor_env.out
@@ -0,0 +1,27 @@
+rainbow
+rainbow/
+rainbow//
+rainbow/broken
+rainbow/chardev_link
+rainbow/exec.sh
+rainbow/file.dat
+rainbow/file.txt
+rainbow/link.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ow
+rainbow/pipe
+rainbow/sgid
+rainbow/socket
+rainbow/sticky
+rainbow/sticky_ow
+rainbow/sugid
+rainbow/suid
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/nocolor_env.sh b/tests/bfs/nocolor_env.sh
new file mode 100644
index 0000000..d1c2afb
--- /dev/null
+++ b/tests/bfs/nocolor_env.sh
@@ -0,0 +1,3 @@
+NO_COLOR=1 bfs_pty rainbow >"$OUT"
+sort_output
+diff_output
diff --git a/tests/bfs/nocolor_env_empty.out b/tests/bfs/nocolor_env_empty.out
new file mode 100644
index 0000000..a439814
--- /dev/null
+++ b/tests/bfs/nocolor_env_empty.out
@@ -0,0 +1,27 @@
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/exec.sh
+rainbow/socket
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sticky_ow
+rainbow/sgid
+rainbow/pipe
+rainbow/ow
+rainbow/sugid
+rainbow/suid
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/nocolor_env_empty.sh b/tests/bfs/nocolor_env_empty.sh
new file mode 100644
index 0000000..1edfb1d
--- /dev/null
+++ b/tests/bfs/nocolor_env_empty.sh
@@ -0,0 +1,3 @@
+NO_COLOR= bfs_pty rainbow >"$OUT"
+sort_output
+diff_output
diff --git a/tests/bfs/nohidden.out b/tests/bfs/nohidden.out
new file mode 100644
index 0000000..d3ec901
--- /dev/null
+++ b/tests/bfs/nohidden.out
@@ -0,0 +1,21 @@
+weirdnames
+weirdnames/
+weirdnames/ /j
+weirdnames/!
+weirdnames/!-
+weirdnames/!-/e
+weirdnames/!/d
+weirdnames/(
+weirdnames/(-
+weirdnames/(-/c
+weirdnames/(/b
+weirdnames/)
+weirdnames/)/g
+weirdnames/,
+weirdnames/,/f
+weirdnames/-
+weirdnames/-/a
+weirdnames/[
+weirdnames/[/k
+weirdnames/\
+weirdnames/\/i
diff --git a/tests/bfs/nohidden.sh b/tests/bfs/nohidden.sh
new file mode 100644
index 0000000..e3a3e4a
--- /dev/null
+++ b/tests/bfs/nohidden.sh
@@ -0,0 +1 @@
+bfs_diff weirdnames -nohidden
diff --git a/tests/bfs/nohidden_depth.out b/tests/bfs/nohidden_depth.out
new file mode 100644
index 0000000..d3ec901
--- /dev/null
+++ b/tests/bfs/nohidden_depth.out
@@ -0,0 +1,21 @@
+weirdnames
+weirdnames/
+weirdnames/ /j
+weirdnames/!
+weirdnames/!-
+weirdnames/!-/e
+weirdnames/!/d
+weirdnames/(
+weirdnames/(-
+weirdnames/(-/c
+weirdnames/(/b
+weirdnames/)
+weirdnames/)/g
+weirdnames/,
+weirdnames/,/f
+weirdnames/-
+weirdnames/-/a
+weirdnames/[
+weirdnames/[/k
+weirdnames/\
+weirdnames/\/i
diff --git a/tests/bfs/nohidden_depth.sh b/tests/bfs/nohidden_depth.sh
new file mode 100644
index 0000000..9fd7017
--- /dev/null
+++ b/tests/bfs/nohidden_depth.sh
@@ -0,0 +1 @@
+bfs_diff weirdnames -depth -nohidden
diff --git a/tests/bfs/nowarn.sh b/tests/bfs/nowarn.sh
new file mode 100644
index 0000000..d9f9ab3
--- /dev/null
+++ b/tests/bfs/nowarn.sh
@@ -0,0 +1,2 @@
+stderr=$(invoke_bfs basic -nowarn -depth -prune 2>&1 >/dev/null)
+[ -z "$stderr" ]
diff --git a/tests/bfs/ok_plus_semicolon.out b/tests/bfs/ok_plus_semicolon.out
new file mode 100644
index 0000000..2a3e14f
--- /dev/null
+++ b/tests/bfs/ok_plus_semicolon.out
@@ -0,0 +1,19 @@
+basic +
+basic/a +
+basic/b +
+basic/c +
+basic/c/d +
+basic/e +
+basic/e/f +
+basic/g +
+basic/g/h +
+basic/i +
+basic/j +
+basic/j/foo +
+basic/k +
+basic/k/foo +
+basic/k/foo/bar +
+basic/l +
+basic/l/foo +
+basic/l/foo/bar +
+basic/l/foo/bar/baz +
diff --git a/tests/bfs/ok_plus_semicolon.sh b/tests/bfs/ok_plus_semicolon.sh
new file mode 100644
index 0000000..57d6103
--- /dev/null
+++ b/tests/bfs/ok_plus_semicolon.sh
@@ -0,0 +1,8 @@
+# The -ok primary shall be equivalent to -exec, except that the use of a
+# <plus-sign> to punctuate the end of the primary expression need not be
+# supported, ...
+#
+# bfs chooses not to support it, for compatibility with most other find
+# implementations.
+
+yes | bfs_diff basic -ok echo {} + \;
diff --git a/tests/bfs/okdir_plus_semicolon.out b/tests/bfs/okdir_plus_semicolon.out
new file mode 100644
index 0000000..1909d27
--- /dev/null
+++ b/tests/bfs/okdir_plus_semicolon.out
@@ -0,0 +1,19 @@
+./a +
+./b +
+./bar +
+./bar +
+./basic +
+./baz +
+./c +
+./d +
+./e +
+./f +
+./foo +
+./foo +
+./foo +
+./g +
+./h +
+./i +
+./j +
+./k +
+./l +
diff --git a/tests/bfs/okdir_plus_semicolon.sh b/tests/bfs/okdir_plus_semicolon.sh
new file mode 100644
index 0000000..d316bd7
--- /dev/null
+++ b/tests/bfs/okdir_plus_semicolon.sh
@@ -0,0 +1 @@
+yes | bfs_diff basic -okdir echo {} + \;
diff --git a/tests/bfs/or_incomplete.sh b/tests/bfs/or_incomplete.sh
new file mode 100644
index 0000000..4af31b6
--- /dev/null
+++ b/tests/bfs/or_incomplete.sh
@@ -0,0 +1 @@
+! invoke_bfs -print -o
diff --git a/tests/bfs/path_expr_flag.out b/tests/bfs/path_expr_flag.out
new file mode 100644
index 0000000..e67f10b
--- /dev/null
+++ b/tests/bfs/path_expr_flag.out
@@ -0,0 +1,2 @@
+links/skip/broken
+links/skip/link
diff --git a/tests/bfs/path_expr_flag.sh b/tests/bfs/path_expr_flag.sh
new file mode 100644
index 0000000..7cfa1cd
--- /dev/null
+++ b/tests/bfs/path_expr_flag.sh
@@ -0,0 +1 @@
+bfs_diff links/skip -type l -H
diff --git a/tests/bfs/path_flag_expr.out b/tests/bfs/path_flag_expr.out
new file mode 100644
index 0000000..e67f10b
--- /dev/null
+++ b/tests/bfs/path_flag_expr.out
@@ -0,0 +1,2 @@
+links/skip/broken
+links/skip/link
diff --git a/tests/bfs/path_flag_expr.sh b/tests/bfs/path_flag_expr.sh
new file mode 100644
index 0000000..ca00c8c
--- /dev/null
+++ b/tests/bfs/path_flag_expr.sh
@@ -0,0 +1 @@
+bfs_diff links/skip -H -type l
diff --git a/tests/bfs/perm_leading_plus_symbolic.out b/tests/bfs/perm_leading_plus_symbolic.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/bfs/perm_leading_plus_symbolic.out
diff --git a/tests/bfs/perm_leading_plus_symbolic.sh b/tests/bfs/perm_leading_plus_symbolic.sh
new file mode 100644
index 0000000..4202ac1
--- /dev/null
+++ b/tests/bfs/perm_leading_plus_symbolic.sh
@@ -0,0 +1 @@
+bfs_diff perms -perm +rwx
diff --git a/tests/bfs/perm_symbolic_double_comma.sh b/tests/bfs/perm_symbolic_double_comma.sh
new file mode 100644
index 0000000..48f9d4b
--- /dev/null
+++ b/tests/bfs/perm_symbolic_double_comma.sh
@@ -0,0 +1 @@
+! invoke_bfs perms -perm a+r,,u+w
diff --git a/tests/bfs/perm_symbolic_missing_action.sh b/tests/bfs/perm_symbolic_missing_action.sh
new file mode 100644
index 0000000..28446ab
--- /dev/null
+++ b/tests/bfs/perm_symbolic_missing_action.sh
@@ -0,0 +1 @@
+! invoke_bfs perms -perm a
diff --git a/tests/bfs/perm_symbolic_trailing_comma.sh b/tests/bfs/perm_symbolic_trailing_comma.sh
new file mode 100644
index 0000000..01bbc16
--- /dev/null
+++ b/tests/bfs/perm_symbolic_trailing_comma.sh
@@ -0,0 +1 @@
+! invoke_bfs perms -perm a+r,
diff --git a/tests/bfs/printf_color.out b/tests/bfs/printf_color.out
new file mode 100644
index 0000000..77d21c3
--- /dev/null
+++ b/tests/bfs/printf_color.out
@@ -0,0 +1,28 @@
+. $'./rainbow/\e[1m' $'\e[0m' $'./rainbow/\e[1m/'$'\e[0m' $'rainbow/\e[1m/'$'\e[0m'
+. . . .
+. . rainbow ./rainbow rainbow
+. ./rainbow exec.sh ./rainbow/exec.sh rainbow/exec.sh
+. ./rainbow $'\e[1m' $'./rainbow/\e[1m' $'rainbow/\e[1m'
+. ./rainbow socket ./rainbow/socket rainbow/socket
+. ./rainbow broken ./rainbow/broken rainbow/broken nowhere
+. ./rainbow chardev_link ./rainbow/chardev_link rainbow/chardev_link /dev/null
+. ./rainbow link.txt ./rainbow/link.txt rainbow/link.txt file.txt
+. ./rainbow sticky_ow ./rainbow/sticky_ow rainbow/sticky_ow
+. ./rainbow sgid ./rainbow/sgid rainbow/sgid
+. ./rainbow pipe ./rainbow/pipe rainbow/pipe
+. ./rainbow ow ./rainbow/ow rainbow/ow
+. ./rainbow sugid ./rainbow/sugid rainbow/sugid
+. ./rainbow suid ./rainbow/suid rainbow/suid
+. ./rainbow sticky ./rainbow/sticky rainbow/sticky
+. ./rainbow file.dat ./rainbow/file.dat rainbow/file.dat
+. ./rainbow file.txt ./rainbow/file.txt rainbow/file.txt
+. ./rainbow lower.gz ./rainbow/lower.gz rainbow/lower.gz
+. ./rainbow lower.tar ./rainbow/lower.tar rainbow/lower.tar
+. ./rainbow lower.tar.gz ./rainbow/lower.tar.gz rainbow/lower.tar.gz
+. ./rainbow lu.tar.GZ ./rainbow/lu.tar.GZ rainbow/lu.tar.GZ
+. ./rainbow mh1 ./rainbow/mh1 rainbow/mh1
+. ./rainbow mh2 ./rainbow/mh2 rainbow/mh2
+. ./rainbow ul.TAR.gz ./rainbow/ul.TAR.gz rainbow/ul.TAR.gz
+. ./rainbow upper.GZ ./rainbow/upper.GZ rainbow/upper.GZ
+. ./rainbow upper.TAR ./rainbow/upper.TAR rainbow/upper.TAR
+. ./rainbow upper.TAR.GZ ./rainbow/upper.TAR.GZ rainbow/upper.TAR.GZ
diff --git a/tests/bfs/printf_color.sh b/tests/bfs/printf_color.sh
new file mode 100644
index 0000000..3641ddb
--- /dev/null
+++ b/tests/bfs/printf_color.sh
@@ -0,0 +1 @@
+bfs_diff -color -exclude \( -depth 1 -not -name rainbow \) -printf '%H %h %f %p %P %l\n'
diff --git a/tests/bfs/printf_duplicate_flag.sh b/tests/bfs/printf_duplicate_flag.sh
new file mode 100644
index 0000000..5ff29f1
--- /dev/null
+++ b/tests/bfs/printf_duplicate_flag.sh
@@ -0,0 +1 @@
+! invoke_bfs basic -printf '%--p'
diff --git a/tests/bfs/printf_everything.sh b/tests/bfs/printf_everything.sh
new file mode 100644
index 0000000..07d574a
--- /dev/null
+++ b/tests/bfs/printf_everything.sh
@@ -0,0 +1,15 @@
+everything=(%{a,b,c,d,D,f,g,G,h,H,i,k,l,m,M,n,p,P,s,S,t,u,U,y,Y})
+
+# Check if we have fstypes
+if invoke_bfs basic -printf '%F' -quit >/dev/null; then
+ everything+=(%F)
+fi
+
+everything+=(%{A,C,T}{%,+,@,a,A,b,B,c,C,d,D,e,F,g,G,h,H,I,j,k,l,m,M,n,p,r,R,s,S,t,T,u,U,V,w,W,x,X,y,Y,z,Z})
+
+# Check if we have birth times
+if invoke_bfs basic -printf '%w' -quit >/dev/null; then
+ everything+=(%w %{B,W}{%,+,@,a,A,b,B,c,C,d,D,e,F,g,G,h,H,I,j,k,l,m,M,n,p,r,R,s,S,t,T,u,U,V,w,W,x,X,y,Y,z,Z})
+fi
+
+invoke_bfs rainbow -printf "${everything[*]}\n" >/dev/null
diff --git a/tests/bfs/printf_incomplete_escape.sh b/tests/bfs/printf_incomplete_escape.sh
new file mode 100644
index 0000000..f560d28
--- /dev/null
+++ b/tests/bfs/printf_incomplete_escape.sh
@@ -0,0 +1 @@
+! invoke_bfs basic -printf '\'
diff --git a/tests/bfs/printf_incomplete_format.sh b/tests/bfs/printf_incomplete_format.sh
new file mode 100644
index 0000000..92c6afc
--- /dev/null
+++ b/tests/bfs/printf_incomplete_format.sh
@@ -0,0 +1 @@
+! invoke_bfs basic -printf '%'
diff --git a/tests/bfs/printf_invalid_escape.sh b/tests/bfs/printf_invalid_escape.sh
new file mode 100644
index 0000000..4338f9b
--- /dev/null
+++ b/tests/bfs/printf_invalid_escape.sh
@@ -0,0 +1 @@
+! invoke_bfs basic -printf '\!'
diff --git a/tests/bfs/printf_invalid_format.sh b/tests/bfs/printf_invalid_format.sh
new file mode 100644
index 0000000..59d63a7
--- /dev/null
+++ b/tests/bfs/printf_invalid_format.sh
@@ -0,0 +1 @@
+! invoke_bfs basic -printf '%!'
diff --git a/tests/bfs/printf_must_be_numeric.sh b/tests/bfs/printf_must_be_numeric.sh
new file mode 100644
index 0000000..7c7c3fa
--- /dev/null
+++ b/tests/bfs/printf_must_be_numeric.sh
@@ -0,0 +1 @@
+! invoke_bfs basic -printf '%+p'
diff --git a/tests/bfs/printf_w.out b/tests/bfs/printf_w.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/bfs/printf_w.out
diff --git a/tests/bfs/printf_w.sh b/tests/bfs/printf_w.sh
new file mode 100644
index 0000000..3b27ee7
--- /dev/null
+++ b/tests/bfs/printf_w.sh
@@ -0,0 +1,2 @@
+# Birth times may not be supported, so just check that %w/%W/%B can be parsed
+bfs_diff times -false -printf '%w %WY %BY\n'
diff --git a/tests/bfs/status.sh b/tests/bfs/status.sh
new file mode 100644
index 0000000..83e12d3
--- /dev/null
+++ b/tests/bfs/status.sh
@@ -0,0 +1 @@
+bfs_pty basic -status -print -depth 0 -exec stty cols 123 rows 14 \; >"$OUT"
diff --git a/tests/bfs/stderr_fails_loudly.sh b/tests/bfs/stderr_fails_loudly.sh
new file mode 100644
index 0000000..8572d5a
--- /dev/null
+++ b/tests/bfs/stderr_fails_loudly.sh
@@ -0,0 +1,2 @@
+test -e /dev/full || skip
+! invoke_bfs -D all basic -false -fprint /dev/full 2>/dev/full
diff --git a/tests/bfs/stderr_fails_silently.out b/tests/bfs/stderr_fails_silently.out
new file mode 100644
index 0000000..a7ccfe4
--- /dev/null
+++ b/tests/bfs/stderr_fails_silently.out
@@ -0,0 +1,19 @@
+basic
+basic/a
+basic/b
+basic/c
+basic/c/d
+basic/e
+basic/e/f
+basic/g
+basic/g/h
+basic/i
+basic/j
+basic/j/foo
+basic/k
+basic/k/foo
+basic/k/foo/bar
+basic/l
+basic/l/foo
+basic/l/foo/bar
+basic/l/foo/bar/baz
diff --git a/tests/bfs/stderr_fails_silently.sh b/tests/bfs/stderr_fails_silently.sh
new file mode 100644
index 0000000..a37393d
--- /dev/null
+++ b/tests/bfs/stderr_fails_silently.sh
@@ -0,0 +1,2 @@
+test -e /dev/full || skip
+bfs_diff -D all basic 2>/dev/full
diff --git a/tests/bfs/type_multi.out b/tests/bfs/type_multi.out
new file mode 100644
index 0000000..3cae08a
--- /dev/null
+++ b/tests/bfs/type_multi.out
@@ -0,0 +1,7 @@
+links
+links/deeply
+links/deeply/nested
+links/deeply/nested/dir
+links/deeply/nested/file
+links/file
+links/hardlink
diff --git a/tests/bfs/type_multi.sh b/tests/bfs/type_multi.sh
new file mode 100644
index 0000000..59992c7
--- /dev/null
+++ b/tests/bfs/type_multi.sh
@@ -0,0 +1 @@
+bfs_diff links -type f,d,c
diff --git a/tests/bfs/typo.sh b/tests/bfs/typo.sh
new file mode 100644
index 0000000..459e9fe
--- /dev/null
+++ b/tests/bfs/typo.sh
@@ -0,0 +1 @@
+invoke_bfs -dikkiq 2>&1 | grep follow >/dev/null
diff --git a/tests/bfs/unexpected_operator.sh b/tests/bfs/unexpected_operator.sh
new file mode 100644
index 0000000..2eb0e71
--- /dev/null
+++ b/tests/bfs/unexpected_operator.sh
@@ -0,0 +1 @@
+! invoke_bfs \! -o -print
diff --git a/tests/bfs/unique.out b/tests/bfs/unique.out
new file mode 100644
index 0000000..289cbde
--- /dev/null
+++ b/tests/bfs/unique.out
@@ -0,0 +1,2 @@
+links/file
+links/symlink
diff --git a/tests/bfs/unique.sh b/tests/bfs/unique.sh
new file mode 100644
index 0000000..ea8adfd
--- /dev/null
+++ b/tests/bfs/unique.sh
@@ -0,0 +1 @@
+bfs_diff links/{file,symlink,hardlink} -unique
diff --git a/tests/bfs/unique_depth.out b/tests/bfs/unique_depth.out
new file mode 100644
index 0000000..a7ccfe4
--- /dev/null
+++ b/tests/bfs/unique_depth.out
@@ -0,0 +1,19 @@
+basic
+basic/a
+basic/b
+basic/c
+basic/c/d
+basic/e
+basic/e/f
+basic/g
+basic/g/h
+basic/i
+basic/j
+basic/j/foo
+basic/k
+basic/k/foo
+basic/k/foo/bar
+basic/l
+basic/l/foo
+basic/l/foo/bar
+basic/l/foo/bar/baz
diff --git a/tests/bfs/unique_depth.sh b/tests/bfs/unique_depth.sh
new file mode 100644
index 0000000..c1d9716
--- /dev/null
+++ b/tests/bfs/unique_depth.sh
@@ -0,0 +1 @@
+bfs_diff basic -unique -depth
diff --git a/tests/bfs/version.sh b/tests/bfs/version.sh
new file mode 100644
index 0000000..e0417ca
--- /dev/null
+++ b/tests/bfs/version.sh
@@ -0,0 +1 @@
+invoke_bfs -version >/dev/null
diff --git a/tests/bfs/warn_O9.out b/tests/bfs/warn_O9.out
new file mode 100644
index 0000000..336a6e8
--- /dev/null
+++ b/tests/bfs/warn_O9.out
@@ -0,0 +1,19 @@
+.
+./a
+./b
+./c
+./c/d
+./e
+./e/f
+./g
+./g/h
+./i
+./j
+./j/foo
+./k
+./k/foo
+./k/foo/bar
+./l
+./l/foo
+./l/foo/bar
+./l/foo/bar/baz
diff --git a/tests/bfs/warn_O9.sh b/tests/bfs/warn_O9.sh
new file mode 100644
index 0000000..821789f
--- /dev/null
+++ b/tests/bfs/warn_O9.sh
@@ -0,0 +1,3 @@
+# Regression test: don't crash when warning if -O9 is the last argument
+cd basic
+bfs_diff -warn -O9
diff --git a/tests/bfs/warn_depth_prune.sh b/tests/bfs/warn_depth_prune.sh
new file mode 100644
index 0000000..0f613c8
--- /dev/null
+++ b/tests/bfs/warn_depth_prune.sh
@@ -0,0 +1,2 @@
+stderr=$(invoke_bfs basic -warn -depth -prune 2>&1 >/dev/null)
+[ -n "$stderr" ]
diff --git a/tests/bfs/warn_exclude_path.sh b/tests/bfs/warn_exclude_path.sh
new file mode 100644
index 0000000..988544e
--- /dev/null
+++ b/tests/bfs/warn_exclude_path.sh
@@ -0,0 +1,2 @@
+stderr=$(invoke_bfs -warn -exclude basic -name '*f*' 2>&1 >/dev/null)
+[ -n "$stderr" ]
diff --git a/tests/bfs/warn_xdev_mount.out b/tests/bfs/warn_xdev_mount.out
new file mode 100644
index 0000000..a7ccfe4
--- /dev/null
+++ b/tests/bfs/warn_xdev_mount.out
@@ -0,0 +1,19 @@
+basic
+basic/a
+basic/b
+basic/c
+basic/c/d
+basic/e
+basic/e/f
+basic/g
+basic/g/h
+basic/i
+basic/j
+basic/j/foo
+basic/k
+basic/k/foo
+basic/k/foo/bar
+basic/l
+basic/l/foo
+basic/l/foo/bar
+basic/l/foo/bar/baz
diff --git a/tests/bfs/warn_xdev_mount.sh b/tests/bfs/warn_xdev_mount.sh
new file mode 100644
index 0000000..5d395f6
--- /dev/null
+++ b/tests/bfs/warn_xdev_mount.sh
@@ -0,0 +1,2 @@
+# Regression test: don't crash if -mount is the last option
+bfs_diff basic -warn -xdev -mount
diff --git a/tests/bfs/xtype_depth.sh b/tests/bfs/xtype_depth.sh
new file mode 100644
index 0000000..02c8173
--- /dev/null
+++ b/tests/bfs/xtype_depth.sh
@@ -0,0 +1,2 @@
+# Make sure -xtype is considered side-effecting for facts_when_impure
+! invoke_bfs loops -xtype l -depth 100
diff --git a/tests/bfs/xtype_multi.out b/tests/bfs/xtype_multi.out
new file mode 100644
index 0000000..558e89c
--- /dev/null
+++ b/tests/bfs/xtype_multi.out
@@ -0,0 +1,10 @@
+links
+links/deeply
+links/deeply/nested
+links/deeply/nested/dir
+links/deeply/nested/file
+links/deeply/nested/link
+links/file
+links/hardlink
+links/skip
+links/symlink
diff --git a/tests/bfs/xtype_multi.sh b/tests/bfs/xtype_multi.sh
new file mode 100644
index 0000000..ed20955
--- /dev/null
+++ b/tests/bfs/xtype_multi.sh
@@ -0,0 +1 @@
+bfs_diff links -xtype f,d,c
diff --git a/tests/bfs/xtype_reorder.out b/tests/bfs/xtype_reorder.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/bfs/xtype_reorder.out
diff --git a/tests/bfs/xtype_reorder.sh b/tests/bfs/xtype_reorder.sh
new file mode 100644
index 0000000..8d75d7d
--- /dev/null
+++ b/tests/bfs/xtype_reorder.sh
@@ -0,0 +1,4 @@
+# Make sure -xtype is not reordered in front of anything -- if -xtype runs
+# before -links 100, it will report an ELOOP error
+bfs_diff loops -links 100 -xtype l
+invoke_bfs loops -links 100 -xtype l