diff --git a/.gitignore b/.gitignore index 65b62036a..37ee9f928 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,7 @@ /src/*/gen_table -/build/ /target/ /tmp/ /busybox/ -/deps/regex/ -/deps/rust-crypto/ -/deps/target/ -/deps/time/ *~ .*.swp .*.swo diff --git a/Cargo.toml b/Cargo.toml index d976558a0..5313c1978 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ version = "0.0.1" authors = [] build = "build.rs" + [features] default = ["all"] all = [ @@ -58,12 +59,13 @@ all = [ "sleep", "sort", "split", + "stdbuf", "sum", "sync", "tac", "tail", "tee", - "test", + "test_uu", "timeout", "touch", "tr", @@ -134,12 +136,13 @@ shuf = { optional=true, path="src/shuf" } sleep = { optional=true, path="src/sleep" } sort = { optional=true, path="src/sort" } split = { optional=true, path="src/split" } +stdbuf = { optional=true, path="src/stdbuf" } sum = { optional=true, path="src/sum" } sync = { optional=true, path="src/sync" } tac = { optional=true, path="src/tac" } tail = { optional=true, path="src/tail" } tee = { optional=true, path="src/tee" } -test = { optional=true, path="src/test" } +test_uu = { optional=true, path="src/test" } timeout = { optional=true, path="src/timeout" } touch = { optional=true, path="src/touch" } tr = { optional=true, path="src/tr" } @@ -157,8 +160,21 @@ wc = { optional=true, path="src/wc" } whoami = { optional=true, path="src/whoami" } yes = { optional=true, path="src/yes" } +[dev-dependencies] +time = "*" +kernel32-sys = "*" +winapi = "*" +filetime = "*" +libc = "*" +memchr = "*" +primal = "*" +aho-corasick= "*" +regex-syntax= "*" +regex="*" +rand="*" +tempdir="*" [[bin]] name="uutils" -path="src/uutils/uutils_cargo.rs" +path="src/uutils/uutils.rs" diff --git a/Makefile b/Makefile index c97bcd906..07828acf7 100644 --- a/Makefile +++ b/Makefile @@ -1,43 +1,30 @@ # Config options -ENABLE_LTO ?= n -ENABLE_STRIP ?= n +ENABLE_RELEASE ?= n +PROFILE ?= debug +MULTICALL ?= n + +PROFILE_CMD := +ifeq (${PROFILE},release) + PROFILE_CMD = --release +endif # Binaries -RUSTC ?= rustc CARGO ?= cargo -CC ?= gcc -RM := rm # Install directories PREFIX ?= /usr/local BINDIR ?= /bin LIBDIR ?= /lib +INSTALLDIR=$(DESTDIR)$(PREFIX) + # This won't support any directory with spaces in its name, but you can just # make a symlink without spaces that points to the directory. BASEDIR ?= $(shell pwd) -SRCDIR := $(BASEDIR)/src -BUILDDIR := $(BASEDIR)/build -TESTDIR := $(BASEDIR)/test -TEMPDIR := $(BASEDIR)/tmp +BUILDDIR := $(BASEDIR)/target/${PROFILE}/ +PKG_BUILDDIR := $(BUILDDIR)/deps/ -# Flags -RUSTCFLAGS := -O -RMFLAGS := -RUSTCLIBFLAGS := $(RUSTCFLAGS) -L $(BUILDDIR)/ -RUSTCTESTFLAGS := $(RUSTCFLAGS) - -# Handle config setup -ifeq ($(ENABLE_LTO),y) -RUSTCBINFLAGS := $(RUSTCLIBFLAGS) -C lto -else -RUSTCBINFLAGS := $(RUSTCLIBFLAGS) -endif - -ifneq ($(ENABLE_STRIP),y) -ENABLE_STRIP := -endif # Possible programs PROGS := \ @@ -83,7 +70,7 @@ PROGS := \ sync \ tac \ tee \ - test \ + test_uu \ tr \ true \ truncate \ @@ -132,17 +119,20 @@ ALIASES := \ BUILD ?= $(PROGS) +TESTS := \ + $(filter $(PROGS),$(filter-out $(DONT_TEST),$(filter $(BUILD),$(filter-out $(DONT_BUILD),$(TEST_PROGS))))) + +TEST ?= $(TEST_PROGS) + # Output names EXES := \ $(sort $(filter $(BUILD),$(filter-out $(DONT_BUILD),$(PROGS)))) -CRATE_RLIBS := - -INSTALL ?= $(EXES) - INSTALLEES := \ $(filter $(INSTALL),$(filter-out $(DONT_INSTALL),$(EXES) uutils)) +INSTALL ?= $(EXES) + # Shared library extension SYSTEM := $(shell uname) DYLIB_EXT := @@ -161,282 +151,57 @@ ifneq (,$(findstring stdbuf, $(INSTALLEES))) LIBS += libstdbuf.$(DYLIB_EXT) endif -# Programs with usable tests -TEST_PROGS := \ - base64 \ - basename \ - cat \ - cksum \ - cp \ - cut \ - env \ - dirname \ - echo \ - factor \ - false \ - fold \ - hashsum \ - head \ - link \ - ln \ - mkdir \ - mv \ - nl \ - paste \ - ptx \ - pwd \ - readlink \ - realpath \ - rm \ - rmdir \ - seq \ - sort \ - split \ - stdbuf \ - sum \ - tac \ - test \ - touch \ - tr \ - true \ - truncate \ - tsort \ - unlink \ - unexpand \ - wc - -TEST ?= $(TEST_PROGS) - -TESTS := \ - $(filter $(TEST),$(filter-out $(DONT_TEST),$(filter $(BUILD),$(filter-out $(DONT_BUILD),$(TEST_PROGS))))) - -# figure out what dependencies we need based on which programs we're building -define DEP_INCLUDE --include $(SRCDIR)/$(1)/deps.mk -endef -# we always depend on libc because common/util does -# we also depend on getopts since all utilities support command-line arguments -DEPLIBS := libc getopts -DEPPLUGS := -# now, add in deps in src/utilname/deps.mk -# if we're testing, only consider the TESTS variable, -# otherwise consider the EXES variable -ifeq ($(MAKECMDGOALS),test) -$(foreach build,$(TESTS),$(eval $(call DEP_INCLUDE,$(build)))) -else -$(foreach build,$(sort $(TESTS) $(EXES)),$(eval $(call DEP_INCLUDE,$(build)))) -endif -# uniqify deps -DEPLIBS := $(sort $(DEPLIBS)) -DEPPLUGS := $(sort $(DEPPLUGS)) -# build --extern commandline for rustc -DEP_EXTERN := $(foreach lib,$(subst -,_,$(DEPLIBS)),--extern $(lib)=$(BUILDDIR)/lib$(lib).rlib) -DEP_EXTERN += $(foreach plug,$(subst -,_,$(DEPPLUGS)),--extern $(plug)=$(BUILDDIR)/lib$(plug).$(DYLIB_EXT)) - -# Setup for building crates -define BUILD_SETUP -X := $(shell $(RUSTC) --print file-names --crate-type rlib $(SRCDIR)/$(1)/$(1).rs) -$(1)_RLIB := $$(X) -CRATE_RLIBS += $$(X) -endef -$(foreach crate,$(EXES),$(eval $(call BUILD_SETUP,$(crate)))) - -# Utils stuff -EXES_PATHS := $(addprefix $(BUILDDIR)/,$(EXES)) -RLIB_PATHS := $(addprefix $(BUILDDIR)/,$(CRATE_RLIBS)) -command = sh -c '$(1)' -RESERVED_EXTERNS := --extern uufalse=$(BUILDDIR)/libfalse.rlib --extern uutrue=$(BUILDDIR)/libtrue.rlib --extern uutest=$(BUILDDIR)/libtest.rlib - -# Main exe build rule -define EXE_BUILD -$(BUILDDIR)/gen/$(1).rs: $(BUILDDIR)/mkmain - $(BUILDDIR)/mkmain $(1) $$@ - -$(BUILDDIR)/$(1): $(BUILDDIR)/gen/$(1).rs $(BUILDDIR)/$($(1)_RLIB) | $(BUILDDIR) deps - $(RUSTC) $(RUSTCBINFLAGS) $(RESERVED_EXTERNS) -o $$@ $$< - $(if $(ENABLE_STRIP),strip $$@,) -endef - -# GRRR rust-crypto makes a crate called "crypto". -# This should NOT be allowed by crates.io. GRRRR. -define DEP_BUILD -DEP_$(1): -ifeq ($(1),crypto) - cd $(BASEDIR)/deps && $(CARGO) build --package rust-crypto --release -else ifeq ($(1),kernel32) - cd $(BASEDIR)/deps && $(CARGO) build --package kernel32-sys --release -else ifeq ($(1),advapi32) - cd $(BASEDIR)/deps && $(CARGO) build --package advapi32-sys --release -else - cd $(BASEDIR)/deps && $(CARGO) build --package $(1) --release -endif -endef - -define CRATE_BUILD --include $(BUILDDIR)/$(1).d - -$(BUILDDIR)/$($(1)_RLIB): $(SRCDIR)/$(1)/$(1).rs | $(BUILDDIR) deps - $(RUSTC) $(RUSTCLIBFLAGS) $(DEP_EXTERN) --crate-type rlib --emit link,dep-info $$< --out-dir $(BUILDDIR) -endef - -# Aliases build rule -ALIAS_SOURCE = $(firstword $(subst :, ,$(1))) -ALIAS_TARGET = $(word 2,$(subst :, ,$(1))) -define MAKE_ALIAS - -ifneq ($(ALIAS_TARGET,$(1)),) -all: $(BUILDDIR)/$(call ALIAS_TARGET,$(1)) -$(BUILDDIR)/$(call ALIAS_TARGET,$(1)): $(BUILDDIR)/$(call ALIAS_SOURCE,$(1)) - $(call command,install $$@ $$<) -endif - -endef - -# Test exe built rules -define TEST_BUILD -test_$(1): $(BUILDDIR)/$(1) $(TEMPDIR)/$(1)/$(1)_test - $(call command,cp $(BUILDDIR)/$(1) $(TEMPDIR)/$(1) && cd $(TEMPDIR)/$(1) && $(TEMPDIR)/$(1)/$(1)_test) - -$(TEMPDIR)/$(1)/$(1)_test: $(TESTDIR)/$(1).rs | $(TEMPDIR)/$(1) - $(call command,$(RUSTC) $(RUSTCTESTFLAGS) $(DEP_EXTERN) --test -o $$@ $$<) - -$(TEMPDIR)/$(1): | $(TEMPDIR) - $(call command,cp -r $(TESTDIR)/fixtures/$(1) $$@ || mkdir $$@) -endef - -# Main rules -all: $(EXES_PATHS) $(BUILDDIR)/uutils - -# Creating necessary rules for each targets -$(foreach crate,$(EXES),$(eval $(call CRATE_BUILD,$(crate)))) -$(foreach exe,$(EXES),$(eval $(call EXE_BUILD,$(exe)))) -$(foreach alias,$(ALIASES),$(eval $(call MAKE_ALIAS,$(alias)))) -$(foreach test,$(TESTS),$(eval $(call TEST_BUILD,$(test)))) -$(foreach dep,$(sort $(DEPLIBS) $(DEPPLUGS)),$(eval $(call DEP_BUILD,$(dep)))) - --include $(BUILDDIR)/uutils.d -$(BUILDDIR)/uutils: $(SRCDIR)/uutils/uutils.rs $(BUILDDIR)/mkuutils $(RLIB_PATHS) - $(BUILDDIR)/mkuutils $(BUILDDIR)/gen/uutils.rs $(EXES) - $(RUSTC) $(RUSTCBINFLAGS) $(RESERVED_EXTERNS) --emit link,dep-info $(BUILDDIR)/gen/uutils.rs --out-dir $(BUILDDIR) - $(if $(ENABLE_STRIP),strip $@) - -# Library for stdbuf -$(BUILDDIR)/libstdbuf.$(DYLIB_EXT): $(SRCDIR)/stdbuf/libstdbuf.rs $(SRCDIR)/stdbuf/libstdbuf.c $(SRCDIR)/stdbuf/libstdbuf.h | $(BUILDDIR) - cd $(SRCDIR)/stdbuf && \ - $(RUSTC) libstdbuf.rs --extern libc=$(BUILDDIR)/liblibc.rlib && \ - $(CC) -c -Wall -Werror -fPIC libstdbuf.c && \ - $(CC) $(DYLIB_FLAGS) -o libstdbuf.$(DYLIB_EXT) liblibstdbuf.a libstdbuf.o && \ - mv *.$(DYLIB_EXT) $(BUILDDIR) && $(RM) *.o && $(RM) *.a - -$(BUILDDIR)/stdbuf: $(BUILDDIR)/libstdbuf.$(DYLIB_EXT) - -deps: $(BUILDDIR) $(SRCDIR)/cksum/crc_table.rs $(addprefix DEP_,$(DEPLIBS) $(DEPPLUGS)) - $(foreach lib,$(subst -,_,$(DEPLIBS)),$(shell cp $(BASEDIR)/deps/target/release/deps/lib$(lib)-*.rlib $(BUILDDIR)/lib$(lib).rlib)) - $(foreach plug,$(subst -,_,$(DEPPLUGS)),$(shell cp $(BASEDIR)/deps/target/release/deps/lib$(plug)-*.$(DYLIB_EXT) $(BUILDDIR)/lib$(plug).$(DYLIB_EXT))) - -$(BUILDDIR)/mkmain: mkmain.rs | $(BUILDDIR) - $(RUSTC) $(RUSTCFLAGS) $< -o $@ - -$(BUILDDIR)/mkuutils: mkuutils.rs | $(BUILDDIR) - $(RUSTC) $(RUSTCFLAGS) $< -o $@ - -$(SRCDIR)/cksum/crc_table.rs: $(SRCDIR)/cksum/gen_table.rs - cd $(SRCDIR)/cksum && $(RUSTC) $(RUSTCBINFLAGS) gen_table.rs && ./gen_table && $(RM) gen_table - -$(SRCDIR)/factor/prime_table.rs: $(SRCDIR)/factor/gen_table.rs - cd $(SRCDIR)/factor && $(RUSTC) $(RUSTCBINFLAGS) gen_table.rs && ./gen_table > $@ && $(RM) gen_table +all: build crates: - echo $(EXES) + echo "okay" $(EXES) -test: $(TEMPDIR) $(addprefix test_,$(TESTS)) - $(RM) -rf $(TEMPDIR) +build_uutils = ${CARGO} build --features "${1}" ${PROFILE_CMD} --no-default-features +build_pkg = ${CARGO} build ${PROFILE_CMD} -p "${1}" +run_integration_tests = ${CARGO} test --test "${1}" +run_unit_tests = ${CARGO} test -p "${l}" +do_install = install ${1} +use_default := 1 + +test: + $(call build_uutils, ${TESTS}) + $(foreach util, ${TESTS}, $(call run_integration_tests, ${util});) + $(foreach util, ${TESTS}, $(call run_unit_tests, ${util});) + +build: + $(call build_uutils,${EXES}) + $(foreach util, ${EXES}, $(call build_pkg,${util});) clean: - $(RM) -rf $(BUILDDIR) $(TEMPDIR) + $(RM) -rf $(BUILDDIR) distclean: clean - cd $(BASEDIR)/deps && $(CARGO) clean && $(CARGO) update + $(CARGO) clean && $(CARGO) update -$(BUILDDIR): - mkdir -p $(BUILDDIR)/gen - -$(TEMPDIR): - $(RM) -rf $(TEMPDIR) - mkdir $(TEMPDIR) - -install: $(addprefix $(BUILDDIR)/,$(INSTALLEES)) - mkdir -p $(DESTDIR)$(PREFIX)$(BINDIR) - for prog in $(INSTALLEES); do \ - install $(BUILDDIR)/$$prog $(DESTDIR)$(PREFIX)$(BINDIR)/$(PROG_PREFIX)$$prog; \ - done - mkdir -p $(DESTDIR)$(PREFIX)$(LIBDIR) - for lib in $(LIBS); do \ - install $(BUILDDIR)/$$lib $(DESTDIR)$(PREFIX)$(LIBDIR)/$$lib; \ - done +build-check: build clean +test-check: test clean # TODO: figure out if there is way for prefixes to work with the symlinks -install-multicall: $(BUILDDIR)/uutils - mkdir -p $(DESTDIR)$(PREFIX)$(BINDIR) - install $(BUILDDIR)/uutils $(DESTDIR)$(PREFIX)$(BINDIR)/$(PROG_PREFIX)uutils - cd $(DESTDIR)$(PREFIX)$(BINDIR) - for prog in $(INSTALLEES); do \ - ln -s $(PROG_PREFIX)uutils $$prog; \ - done - mkdir -p $(DESTDIR)$(PREFIX)$(LIBDIR) - for lib in $(LIBS); do \ - install $(BUILDDIR)/$$lib $(DESTDIR)$(PREFIX)$(LIBDIR)/$$lib; \ - done +install: build + PROFILE_CMD=--release + mkdir -p $(INSTALLDIR)$(BINDIR) +ifeq (${MULTICALL}, y) + install $(BUILDDIR)/uutils $(INSTALLDIR)$(BINDIR)/$(PROG_PREFIX)uutils + cd $(INSTALLDIR)$(BINDIR) + $(foreach prog, $(INSTALLEES), ln -s $(PROG_PREFIX)uutils $$prog;) +else + $(foreach prog, $(INSTALLEES); \ + install $(PKG_BUILDDIR)/$$prog $(INSTALLDIR)$(BINDIR)/$(PROG_PREFIX)$$prog;) +endif + mkdir -p $(INSTALLDIR)$(LIBDIR) + $(foreach lib, $(LIBS), install $(BUILDDIR)/$$lib $(INSTALLDIR)$(LIBDIR)/$$lib;) uninstall: - rm -f $(addprefix $(DESTDIR)$(PREFIX)$(BINDIR)/$(PROG_PREFIX),$(PROGS)) - rm -f $(addprefix $(DESTDIR)$(PREFIX)$(LIBDIR)/,$(LIBS)) + rm -f $(addprefix $(INSTALLDIR)$(BINDIR)/$(PROG_PREFIX),$(PROGS)) + rm -f $(addprefix $(INSTALLDIR)$(LIBDIR)/,$(LIBS)) uninstall-multicall: - rm -f $(addprefix $(DESTDIR)$(PREFIX)$(BINDIR)/,$(PROGS) $(PROG_PREFIX)uutils) - rm -f $(addprefix $(DESTDIR)$(PREFIX)$(LIBDIR)/,$(LIBS)) + rm -f $(addprefix $(INSTALLDIR)$(BINDIR)/,$(PROGS) $(PROG_PREFIX)uutils) + rm -f $(addprefix $(INSTALLDIR)$(LIBDIR)/,$(LIBS)) -# Test under the busybox testsuite -$(BUILDDIR)/busybox: $(BUILDDIR)/uutils - rm -f $(BUILDDIR)/busybox - ln -s $(BUILDDIR)/uutils $(BUILDDIR)/busybox - -# This is a busybox-specific config file their test suite wants to parse. -$(BUILDDIR)/.config: $(BASEDIR)/.busybox-config $(BUILDDIR)/uutils - cp $< $@ - -ifeq ($(BUSYBOX_SRC),) -busytest: - @echo - @echo "To run \`busytest\` set BUSYBOX_SRC to the directory of the compiled busybox source code." - @echo "Optionally set RUNTEST_ARGS to arguments to pass to the busybox \`runtest\` program." - @echo - @false -else -busytest: $(BUILDDIR)/busybox $(BUILDDIR)/.config - (cd $(BUSYBOX_SRC)/testsuite && bindir=$(BUILDDIR) ./runtest $(RUNTEST_ARGS)) -endif - -# This rule will build each program, ignore all output, and return pass -# or fail depending on whether the build has errors. -build-check: - @for prog in $(sort $(PROGS)); do \ - make BUILD="$$prog" >/dev/null 2>&1; status=$$?; \ - if [ $$status -eq 0 ]; \ - then printf "%-10s\t\033[1;32mpass\033[00;m\n" $$prog; \ - else printf "%-10s\t\033[1;31mfail\033[00;m\n" $$prog; \ - fi; \ - done - -# This rule will test each program, ignore all output, and return pass -# or fail depending on whether the test has errors. -test-check: - @for prog in $(sort $(TEST_PROGS)); do \ - make TEST="$$prog" test >/dev/null 2>&1; status=$$?; \ - if [ $$status -eq 0 ]; \ - then printf "%-10s\t\033[1;32mpass\033[00;m\n" $$prog; \ - else printf "%-10s\t\033[1;31mfail\033[00;m\n" $$prog; \ - fi; \ - done - -.PHONY: $(TEMPDIR) all deps test distclean clean busytest install uninstall +.PHONY: $(TEMPDIR) all build test distclean clean busytest install uninstall diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index b571c1390..000000000 --- a/appveyor.yml +++ /dev/null @@ -1,33 +0,0 @@ -platform: - - x64 - -environment: - global: - MSYS2_BASEVER: 20150512 - MSYS2_ARCH: x86_64 - MBASH: msys64\usr\bin\sh --login -c - - matrix: - - TARGET: i686-pc-windows-gnu - -install: - - appveyor DownloadFile "http://kent.dl.sourceforge.net/project/msys2/Base/%MSYS2_ARCH%/msys2-base-%MSYS2_ARCH%-%MSYS2_BASEVER%.tar.xz" -FileName "msys2.tar.xz" - - 7z x msys2.tar.xz - - 7z x msys2.tar > NUL - - call %MBASH% "" - - call %MBASH% "for i in {1..3}; do pacman --noconfirm -Suy mingw-w64-%MSYS2_ARCH%-{ragel,freetype,icu,gettext} libtool pkg-config gcc make autoconf automake perl && break || sleep 15; done" - - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:TARGET}.exe" - - rust-nightly-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust" - - call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" amd64 - - SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin - - SET PATH=%PATH%;C:\MinGW\bin - - rustc -V - - cargo -V - -build_script: - - call %MBASH% "cd $APPVEYOR_BUILD_FOLDER; PATH=$PATH:/mingw64/bin:/mingw32/bin; exec 0 = env::args().collect(); - if args.len() != 3 { - println!("usage: mkbuild "); - std::process::exit(1); - } - - let crat = match &args[1][..] { - "false" => "uufalse", - "test" => "uutest", - "true" => "uutrue", - _ => &args[1][..], - }; - let outfile = &args[2][..]; - - let main = TEMPLATE.replace("@UTIL_CRATE@", crat); - match File::create(outfile) { - Ok(mut out) => match out.write_all(main.as_bytes()) { - Err(e) => panic!("{}", e), - _ => (), - }, - Err(e) => panic!("{}", e), - } -} diff --git a/mkuutils.rs b/mkuutils.rs deleted file mode 100644 index 772b68435..000000000 --- a/mkuutils.rs +++ /dev/null @@ -1,63 +0,0 @@ -use std::env; -use std::fs::File; -use std::io::{Read, Write}; - -fn main() { - let args : Vec = env::args().collect(); - if args.len() < 3 { - println!("usage: mkuutils "); - std::process::exit(1); - } - - let mut crates = String::new(); - let mut util_map = String::new(); - let mut hashsum = false; - for prog in args[2..].iter() { - match &prog[..] { - "hashsum" | "md5sum" | "sha1sum" | "sha224sum" | "sha256sum" | "sha384sum" | "sha512sum" => { - if !hashsum { - crates.push_str("extern crate hashsum;\n"); - util_map.push_str("map.insert(\"hashsum\", hashsum::uumain);\n"); - util_map.push_str("map.insert(\"md5sum\", hashsum::uumain);\n"); - util_map.push_str("map.insert(\"sha1sum\", hashsum::uumain);\n"); - util_map.push_str("map.insert(\"sha224sum\", hashsum::uumain);\n"); - util_map.push_str("map.insert(\"sha256sum\", hashsum::uumain);\n"); - util_map.push_str("map.insert(\"sha384sum\", hashsum::uumain);\n"); - util_map.push_str("map.insert(\"sha512sum\", hashsum::uumain);\n"); - hashsum = true; - } - }, - "true" => { - util_map.push_str("fn uutrue(_: Vec) -> i32 { 0 }\n"); - util_map.push_str("map.insert(\"true\", uutrue as fn(Vec) -> i32);\n"); - }, - "false" => { - util_map.push_str("fn uufalse(_: Vec) -> i32 { 1 }\n"); - util_map.push_str("map.insert(\"false\", uufalse as fn(Vec) -> i32);\n"); - }, - _ => { - if prog == "test" { - crates.push_str(&(format!("extern crate uu{0} as uu{0};\n", prog))[..]); - } else { - crates.push_str(&(format!("extern crate {0} as uu{0};\n", prog))[..]); - } - util_map.push_str(&(format!("map.insert(\"{prog}\", uu{prog}::uumain as fn(Vec) -> i32);\n", prog = prog))[..]); - } - } - } - let outfile = &(args[1])[..]; - - // XXX: this all just assumes that the IO works correctly - let mut out = File::create(outfile).unwrap(); - let mut input = File::open("src/uutils/uutils.rs").unwrap(); - - let mut template = String::new(); - input.read_to_string(&mut template).unwrap(); - let template = template; - - let main = template.replace("@CRATES@", &crates[..]).replace("@UTIL_MAP@", &util_map[..]); - match out.write_all(main.as_bytes()) { - Err(e) => panic!("{}", e), - _ => (), - } -} diff --git a/src/base64/Cargo.toml b/src/base64/Cargo.toml index 6e0c8ec1f..2d379acea 100644 --- a/src/base64/Cargo.toml +++ b/src/base64/Cargo.toml @@ -11,3 +11,7 @@ path = "base64.rs" getopts = "*" libc = "*" rustc-serialize = "*" + +[[bin]] +name="base64" +path="base64.rs" diff --git a/src/base64/base64.rs b/src/base64/base64.rs index 3ea79a7c3..0fa88de1a 100644 --- a/src/base64/base64.rs +++ b/src/base64/base64.rs @@ -160,3 +160,8 @@ fn help(opts: Options) { fn version() { println!("{} {}", NAME, VERSION); } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/base64/deps.mk b/src/base64/deps.mk deleted file mode 100644 index 5f486e20e..000000000 --- a/src/base64/deps.mk +++ /dev/null @@ -1 +0,0 @@ -DEPLIBS += rustc-serialize diff --git a/src/basename/Cargo.toml b/src/basename/Cargo.toml index ade2a3236..82f68686c 100644 --- a/src/basename/Cargo.toml +++ b/src/basename/Cargo.toml @@ -10,3 +10,7 @@ path = "basename.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="basename" +path="basename.rs" diff --git a/src/basename/basename.rs b/src/basename/basename.rs index 95736067d..4fa9d4df9 100644 --- a/src/basename/basename.rs +++ b/src/basename/basename.rs @@ -106,3 +106,8 @@ fn strip_suffix(name: &str, suffix: &str) -> String { name.to_string() } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/cat/Cargo.toml b/src/cat/Cargo.toml index 36066a55f..1bcb50c16 100644 --- a/src/cat/Cargo.toml +++ b/src/cat/Cargo.toml @@ -10,3 +10,7 @@ path = "cat.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="cat" +path="cat.rs" diff --git a/src/cat/cat.rs b/src/cat/cat.rs index 61629734e..cfc65e668 100644 --- a/src/cat/cat.rs +++ b/src/cat/cat.rs @@ -18,9 +18,8 @@ use getopts::Options; use std::fs::File; use std::intrinsics::{copy_nonoverlapping}; use std::io::{stdout, stdin, stderr, Write, Read, Result}; -use libc::consts::os::posix88::STDIN_FILENO; -use libc::funcs::posix88::unistd::isatty; -use libc::types::os::arch::c95::c_int; +use libc::STDIN_FILENO; +use libc::{c_int, isatty}; #[path = "../common/util.rs"] #[macro_use] @@ -345,3 +344,8 @@ impl<'a, W: Write> Drop for UnsafeWriter<'a, W> { } /* vim: set ai ts=4 sw=4 sts=4 et : */ + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/chmod/Cargo.toml b/src/chmod/Cargo.toml index 5d1508101..d97b17592 100644 --- a/src/chmod/Cargo.toml +++ b/src/chmod/Cargo.toml @@ -15,3 +15,7 @@ memchr = "*" regex = "*" regex-syntax = "*" walker = "*" + +[[bin]] +name="chmod" +path="chmod.rs" diff --git a/src/chmod/chmod.rs b/src/chmod/chmod.rs index 958e56390..21ba9d7c5 100644 --- a/src/chmod/chmod.rs +++ b/src/chmod/chmod.rs @@ -324,3 +324,8 @@ fn chmod_file(file: &Path, name: &str, changes: bool, quiet: bool, verbose: bool Ok(()) } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/chmod/deps.mk b/src/chmod/deps.mk deleted file mode 100644 index 07a0616b6..000000000 --- a/src/chmod/deps.mk +++ /dev/null @@ -1 +0,0 @@ -DEPLIBS += aho-corasick memchr regex regex-syntax walker diff --git a/src/chroot/Cargo.toml b/src/chroot/Cargo.toml index 25c36d15f..2c6bfc660 100644 --- a/src/chroot/Cargo.toml +++ b/src/chroot/Cargo.toml @@ -10,3 +10,7 @@ path = "chroot.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="chroot" +path="chroot.rs" diff --git a/src/chroot/chroot.rs b/src/chroot/chroot.rs index 6ea2699df..7575ca401 100644 --- a/src/chroot/chroot.rs +++ b/src/chroot/chroot.rs @@ -14,7 +14,7 @@ extern crate libc; use c_types::{get_pw_from_args, get_group}; use getopts::Options; -use libc::funcs::posix88::unistd::{setgid, setuid}; +use libc::{setgid, setuid}; use std::ffi::CString; use std::io::{Error, Write}; use std::iter::FromIterator; @@ -218,3 +218,8 @@ If $(SHELL) is not set, /bin/sh is used.", NAME, VERSION); print!("{}", options.usage(&msg)); } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/cksum/Cargo.toml b/src/cksum/Cargo.toml index a76fd6dc4..b6685f0fa 100644 --- a/src/cksum/Cargo.toml +++ b/src/cksum/Cargo.toml @@ -10,3 +10,7 @@ path = "cksum.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="cksum" +path="cksum.rs" diff --git a/src/cksum/cksum.rs b/src/cksum/cksum.rs index 02696ba62..8b0823c16 100644 --- a/src/cksum/cksum.rs +++ b/src/cksum/cksum.rs @@ -129,3 +129,8 @@ Print CRC and size for each file.", NAME, VERSION); exit_code } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/comm/Cargo.toml b/src/comm/Cargo.toml index 214a0ea22..3e5e77a56 100644 --- a/src/comm/Cargo.toml +++ b/src/comm/Cargo.toml @@ -10,3 +10,7 @@ path = "comm.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="comm" +path="comm.rs" diff --git a/src/comm/comm.rs b/src/comm/comm.rs index ded6a83cb..5518f6461 100644 --- a/src/comm/comm.rs +++ b/src/comm/comm.rs @@ -158,3 +158,8 @@ Compare sorted files line by line.", NAME, VERSION); 0 } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/common/c_types.rs b/src/common/c_types.rs index d41871257..0f0dbdb46 100644 --- a/src/common/c_types.rs +++ b/src/common/c_types.rs @@ -13,7 +13,7 @@ use self::libc::time_t; #[cfg(target_os = "macos")] use self::libc::int32_t; -use self::libc::funcs::posix88::unistd::getgroups; +use self::libc::getgroups; use std::ffi::{CStr, CString}; use std::io::{Error, Write}; diff --git a/src/common/process.rs b/src/common/process.rs index 7f098a722..d5ac317ea 100644 --- a/src/common/process.rs +++ b/src/common/process.rs @@ -8,7 +8,6 @@ */ extern crate libc; -extern crate time; use libc::{c_int, pid_t}; use std::fmt; @@ -17,6 +16,7 @@ use std::process::Child; use std::sync::{Arc, Condvar, Mutex}; use std::thread; use time::{Duration, get_time}; +use std::time::Duration as StdDuration; // This is basically sys::unix::process::ExitStatus #[derive(PartialEq, Eq, Clone, Copy, Debug)] @@ -76,8 +76,8 @@ pub trait ChildExt { impl ChildExt for Child { fn send_signal(&mut self, signal: usize) -> io::Result<()> { - if unsafe { libc::funcs::posix88::signal::kill(self.id() as pid_t, - signal as i32) } != 0 { + if unsafe { libc::kill(self.id() as pid_t, + signal as i32) } != 0 { Err(io::Error::last_os_error()) } else { Ok(()) @@ -125,7 +125,7 @@ impl ChildExt for Child { return Ok(None) } let ms = (target - get_time()).num_milliseconds() as u32; - exitstatus = cvar.wait_timeout_ms(exitstatus, ms).unwrap().0; + exitstatus = cvar.wait_timeout(exitstatus, StdDuration::new(0, ms*1000)).unwrap().0; } // Turn Option> into Result> diff --git a/src/cp/Cargo.toml b/src/cp/Cargo.toml index b443112d6..32f7d0e8f 100644 --- a/src/cp/Cargo.toml +++ b/src/cp/Cargo.toml @@ -10,3 +10,7 @@ path = "cp.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="cp" +path="cp.rs" diff --git a/src/cp/cp.rs b/src/cp/cp.rs index 3c0fa2944..18dd12093 100644 --- a/src/cp/cp.rs +++ b/src/cp/cp.rs @@ -159,3 +159,8 @@ pub fn paths_refer_to_same_file(p1: &Path, p2: &Path) -> Result { Ok(pathbuf1 == pathbuf2) } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/cut/.gitignore b/src/cut/.gitignore new file mode 100644 index 000000000..1de565933 --- /dev/null +++ b/src/cut/.gitignore @@ -0,0 +1 @@ +target \ No newline at end of file diff --git a/src/cut/Cargo.toml b/src/cut/Cargo.toml index dc3d30ca9..3c28bf93c 100644 --- a/src/cut/Cargo.toml +++ b/src/cut/Cargo.toml @@ -10,3 +10,7 @@ path = "cut.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="cut" +path="cut.rs" diff --git a/src/cut/cut.rs b/src/cut/cut.rs index 1381e115b..c27849de5 100644 --- a/src/cut/cut.rs +++ b/src/cut/cut.rs @@ -544,3 +544,8 @@ pub fn uumain(args: Vec) -> i32 { } } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/dirname/Cargo.toml b/src/dirname/Cargo.toml index 8c4e65c75..74c8ebc16 100644 --- a/src/dirname/Cargo.toml +++ b/src/dirname/Cargo.toml @@ -10,3 +10,7 @@ path = "dirname.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="dirname" +path="dirname.rs" diff --git a/src/dirname/dirname.rs b/src/dirname/dirname.rs index 0ad6f68e5..c1a3ce60f 100644 --- a/src/dirname/dirname.rs +++ b/src/dirname/dirname.rs @@ -68,3 +68,8 @@ directory).", NAME, VERSION); 0 } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/du/Cargo.toml b/src/du/Cargo.toml index dd6851c34..2bbeba09e 100644 --- a/src/du/Cargo.toml +++ b/src/du/Cargo.toml @@ -11,3 +11,7 @@ path = "du.rs" getopts = "*" libc = "*" time = "*" + +[[bin]] +name="du" +path="du.rs" diff --git a/src/du/deps.mk b/src/du/deps.mk deleted file mode 100644 index bc0c2cf05..000000000 --- a/src/du/deps.mk +++ /dev/null @@ -1 +0,0 @@ -DEPLIBS += time kernel32 winapi diff --git a/src/du/du.rs b/src/du/du.rs index b80d1f193..b1cbb1ad7 100644 --- a/src/du/du.rs +++ b/src/du/du.rs @@ -396,3 +396,8 @@ Try '{} --help' for more information.", s, NAME); 0 } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/echo/Cargo.toml b/src/echo/Cargo.toml index 1e56ce491..deddcf2e4 100644 --- a/src/echo/Cargo.toml +++ b/src/echo/Cargo.toml @@ -10,3 +10,7 @@ path = "echo.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="echo" +path="echo.rs" diff --git a/src/echo/echo.rs b/src/echo/echo.rs index f7e9bae2b..9102287d9 100644 --- a/src/echo/echo.rs +++ b/src/echo/echo.rs @@ -252,3 +252,8 @@ pub fn uumain(args: Vec) -> i32 { 0 } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/env/Cargo.toml b/src/env/Cargo.toml index 69d049a76..7edb50740 100644 --- a/src/env/Cargo.toml +++ b/src/env/Cargo.toml @@ -10,3 +10,7 @@ path = "env.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="env" +path="env.rs" diff --git a/src/env/env.rs b/src/env/env.rs index 89fc38718..b40c44942 100644 --- a/src/env/env.rs +++ b/src/env/env.rs @@ -205,3 +205,8 @@ pub fn uumain(args: Vec) -> i32 { 0 } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(env::args().collect())); +} diff --git a/src/expand/Cargo.toml b/src/expand/Cargo.toml index 75176539a..1924ca905 100644 --- a/src/expand/Cargo.toml +++ b/src/expand/Cargo.toml @@ -11,3 +11,7 @@ path = "expand.rs" getopts = "*" libc = "*" unicode-width = "*" + +[[bin]] +name="expand" +path="expand.rs" diff --git a/src/expand/deps.mk b/src/expand/deps.mk deleted file mode 100644 index fb8005c0c..000000000 --- a/src/expand/deps.mk +++ /dev/null @@ -1 +0,0 @@ -DEPLIBS += unicode-width diff --git a/src/expand/expand.rs b/src/expand/expand.rs index 09bf427b1..a64313206 100644 --- a/src/expand/expand.rs +++ b/src/expand/expand.rs @@ -242,3 +242,8 @@ fn expand(options: Options) { } } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/expr/Cargo.toml b/src/expr/Cargo.toml index 164c2070d..31793d6b1 100644 --- a/src/expr/Cargo.toml +++ b/src/expr/Cargo.toml @@ -11,3 +11,7 @@ path = "expr.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="expr" +path="expr.rs" diff --git a/src/expr/expr.rs b/src/expr/expr.rs index d6a7664d2..9a461b68b 100644 --- a/src/expr/expr.rs +++ b/src/expr/expr.rs @@ -133,3 +133,8 @@ Environment variables: fn print_version() { println!("{} {}", NAME, VERSION); } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/factor/Cargo.toml b/src/factor/Cargo.toml index ab32fae68..2cbb4e9d4 100644 --- a/src/factor/Cargo.toml +++ b/src/factor/Cargo.toml @@ -11,3 +11,7 @@ path = "factor.rs" getopts = "*" libc = "*" rand = "*" + +[[bin]] +name="factor" +path="factor.rs" diff --git a/src/factor/deps.mk b/src/factor/deps.mk deleted file mode 100644 index ea0f8a6b8..000000000 --- a/src/factor/deps.mk +++ /dev/null @@ -1 +0,0 @@ -DEPLIBS += rand diff --git a/src/factor/factor.rs b/src/factor/factor.rs index b037be020..92254370f 100644 --- a/src/factor/factor.rs +++ b/src/factor/factor.rs @@ -200,3 +200,8 @@ read from standard input.", NAME, VERSION); } 0 } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/false/Cargo.toml b/src/false/Cargo.toml index e101245ec..15e1690a2 100644 --- a/src/false/Cargo.toml +++ b/src/false/Cargo.toml @@ -10,3 +10,7 @@ path = "false.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="false" +path="false.rs" diff --git a/src/false/false.rs b/src/false/false.rs index bd19e7dea..0363495be 100644 --- a/src/false/false.rs +++ b/src/false/false.rs @@ -12,3 +12,8 @@ pub fn uumain(_: Vec) -> i32 { 1 } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/fmt/Cargo.toml b/src/fmt/Cargo.toml index 3c3f3fa93..14d16f529 100644 --- a/src/fmt/Cargo.toml +++ b/src/fmt/Cargo.toml @@ -11,3 +11,7 @@ path = "fmt.rs" getopts = "*" libc = "*" unicode-width = "*" + +[[bin]] +name="fmt" +path="fmt.rs" diff --git a/src/fmt/deps.mk b/src/fmt/deps.mk deleted file mode 100644 index fb8005c0c..000000000 --- a/src/fmt/deps.mk +++ /dev/null @@ -1 +0,0 @@ -DEPLIBS += unicode-width diff --git a/src/fmt/fmt.rs b/src/fmt/fmt.rs index 9d2b2df2e..1e0067e8f 100644 --- a/src/fmt/fmt.rs +++ b/src/fmt/fmt.rs @@ -219,3 +219,8 @@ pub fn uumain(args: Vec) -> i32 { 0 } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/fold/Cargo.toml b/src/fold/Cargo.toml index 54bb67150..9712b86ef 100644 --- a/src/fold/Cargo.toml +++ b/src/fold/Cargo.toml @@ -10,3 +10,7 @@ path = "fold.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="fold" +path="fold.rs" diff --git a/src/fold/fold.rs b/src/fold/fold.rs index 5b8da31cd..367e0360f 100644 --- a/src/fold/fold.rs +++ b/src/fold/fold.rs @@ -220,3 +220,8 @@ fn rfind_whitespace(slice: &str) -> Option { } None } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/groups/Cargo.toml b/src/groups/Cargo.toml index ad8f0c86d..0f6a05413 100644 --- a/src/groups/Cargo.toml +++ b/src/groups/Cargo.toml @@ -10,3 +10,7 @@ path = "groups.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="groups" +path="groups.rs" diff --git a/src/groups/groups.rs b/src/groups/groups.rs index 167905111..4883efd34 100644 --- a/src/groups/groups.rs +++ b/src/groups/groups.rs @@ -50,3 +50,8 @@ Prints the groups a user is in to standard output.", NAME, VERSION); 0 } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/hashsum/Cargo.toml b/src/hashsum/Cargo.toml index 78111a679..fa0547553 100644 --- a/src/hashsum/Cargo.toml +++ b/src/hashsum/Cargo.toml @@ -13,3 +13,7 @@ libc = "*" regex = "*" regex-syntax = "*" rust-crypto = "*" + +[[bin]] +name="hashsum" +path="hashsum.rs" diff --git a/src/hashsum/deps.mk b/src/hashsum/deps.mk deleted file mode 100644 index 83178fa58..000000000 --- a/src/hashsum/deps.mk +++ /dev/null @@ -1 +0,0 @@ -DEPLIBS += regex regex-syntax crypto rand rustc-serialize time winapi kernel32 diff --git a/src/hashsum/hashsum.rs b/src/hashsum/hashsum.rs index a47aa1ca1..7afd0d40a 100644 --- a/src/hashsum/hashsum.rs +++ b/src/hashsum/hashsum.rs @@ -307,3 +307,8 @@ fn digest_reader<'a, T: Read>(digest: &mut Box, reader: &mut BufReade Ok(digest.result_str()) } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/head/Cargo.toml b/src/head/Cargo.toml index 42341acc1..e5f012e16 100644 --- a/src/head/Cargo.toml +++ b/src/head/Cargo.toml @@ -10,3 +10,7 @@ path = "head.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="head" +path="head.rs" diff --git a/src/head/head.rs b/src/head/head.rs index 17790c969..cc61e6521 100644 --- a/src/head/head.rs +++ b/src/head/head.rs @@ -208,3 +208,8 @@ fn head(reader: &mut BufReader, settings: &Settings) -> bool { fn version() { println!("{} {}", NAME, VERSION); } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/hostid/Cargo.toml b/src/hostid/Cargo.toml index 146c0879e..796e96457 100644 --- a/src/hostid/Cargo.toml +++ b/src/hostid/Cargo.toml @@ -10,3 +10,7 @@ path = "hostid.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="hostid" +path="hostid.rs" diff --git a/src/hostid/hostid.rs b/src/hostid/hostid.rs index 9cca3d7c5..30fe092ca 100644 --- a/src/hostid/hostid.rs +++ b/src/hostid/hostid.rs @@ -88,3 +88,8 @@ fn hostid() { result &= 0xffffffff; println!("{:0>8x}", result); } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/hostname/Cargo.toml b/src/hostname/Cargo.toml index 2d2db8ee1..6f67767dc 100644 --- a/src/hostname/Cargo.toml +++ b/src/hostname/Cargo.toml @@ -10,3 +10,7 @@ path = "hostname.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="hostname" +path="hostname.rs" diff --git a/src/hostname/hostname.rs b/src/hostname/hostname.rs index d22a8d9e3..6353f7c6c 100644 --- a/src/hostname/hostname.rs +++ b/src/hostname/hostname.rs @@ -174,3 +174,8 @@ fn xsethostname(name: &str) { println!("Cannot set hostname to {}", name); } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/id/Cargo.toml b/src/id/Cargo.toml index 39035c77a..c2803d60f 100644 --- a/src/id/Cargo.toml +++ b/src/id/Cargo.toml @@ -10,3 +10,7 @@ path = "id.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="id" +path="id.rs" diff --git a/src/id/id.rs b/src/id/id.rs index ca3f07e83..5d5f74f79 100644 --- a/src/id/id.rs +++ b/src/id/id.rs @@ -17,8 +17,7 @@ extern crate getopts; extern crate libc; -use libc::{getgid, getuid, uid_t}; -use libc::funcs::posix88::unistd::{getegid, geteuid, getlogin}; +use libc::{getgid, getuid, uid_t, getegid, geteuid, getlogin}; use std::ffi::CStr; use std::io::Write; use std::ptr::read; @@ -395,3 +394,8 @@ fn id_print(possible_pw: Option, p_euid: bool, p_egid: bool) { println!(""); } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/kill/Cargo.toml b/src/kill/Cargo.toml index 7f36a1bd6..cb0939dea 100644 --- a/src/kill/Cargo.toml +++ b/src/kill/Cargo.toml @@ -10,3 +10,7 @@ path = "kill.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="kill" +path="kill.rs" diff --git a/src/kill/kill.rs b/src/kill/kill.rs index 1556a2807..99aa40178 100644 --- a/src/kill/kill.rs +++ b/src/kill/kill.rs @@ -182,7 +182,7 @@ fn kill(signalname: &str, pids: std::vec::Vec) -> i32 { for pid in pids.iter() { match pid.parse::() { Ok(x) => { - if unsafe { libc::funcs::posix88::signal::kill(x as pid_t, signal_value as c_int) } != 0 { + if unsafe { libc::kill(x as pid_t, signal_value as c_int) } != 0 { show_error!("{}", Error::last_os_error()); status = 1; } @@ -192,3 +192,8 @@ fn kill(signalname: &str, pids: std::vec::Vec) -> i32 { } status } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/link/Cargo.toml b/src/link/Cargo.toml index 84044b784..c762bd738 100644 --- a/src/link/Cargo.toml +++ b/src/link/Cargo.toml @@ -10,3 +10,7 @@ path = "link.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="link" +path="link.rs" diff --git a/src/link/link.rs b/src/link/link.rs index a762550b7..3777b0444 100644 --- a/src/link/link.rs +++ b/src/link/link.rs @@ -64,3 +64,8 @@ Create a link named FILE2 to FILE1.", NAME, VERSION); } } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/ln/Cargo.toml b/src/ln/Cargo.toml index 8ec3cb1d7..f617aa8e0 100644 --- a/src/ln/Cargo.toml +++ b/src/ln/Cargo.toml @@ -10,3 +10,7 @@ path = "ln.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="ln" +path="ln.rs" diff --git a/src/ln/ln.rs b/src/ln/ln.rs index 6a7646e93..5c2a9c866 100644 --- a/src/ln/ln.rs +++ b/src/ln/ln.rs @@ -331,3 +331,8 @@ pub fn is_symlink>(path: P) -> bool { Err(_) => false } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/logname/Cargo.toml b/src/logname/Cargo.toml index b207e91bf..2fc373c2e 100644 --- a/src/logname/Cargo.toml +++ b/src/logname/Cargo.toml @@ -10,3 +10,7 @@ path = "logname.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="logname" +path="logname.rs" diff --git a/src/logname/logname.rs b/src/logname/logname.rs index c587bf038..39c1fc3c6 100644 --- a/src/logname/logname.rs +++ b/src/logname/logname.rs @@ -79,3 +79,8 @@ fn exec() { None => println!("{}: no login name", NAME) } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/mkdir/Cargo.toml b/src/mkdir/Cargo.toml index 11f916bb0..1afcf60c6 100644 --- a/src/mkdir/Cargo.toml +++ b/src/mkdir/Cargo.toml @@ -10,3 +10,7 @@ path = "mkdir.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="mkdir" +path="mkdir.rs" diff --git a/src/mkdir/mkdir.rs b/src/mkdir/mkdir.rs index b68fe0d09..7fce74011 100644 --- a/src/mkdir/mkdir.rs +++ b/src/mkdir/mkdir.rs @@ -158,3 +158,8 @@ fn mkdir(path: &Path, mode: u16, verbose: bool) -> i32 { } chmod(path, mode) } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/mkfifo/Cargo.toml b/src/mkfifo/Cargo.toml index a8b347e2c..c733a2cb9 100644 --- a/src/mkfifo/Cargo.toml +++ b/src/mkfifo/Cargo.toml @@ -10,3 +10,7 @@ path = "mkfifo.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="mkfifo" +path="mkfifo.rs" diff --git a/src/mkfifo/mkfifo.rs b/src/mkfifo/mkfifo.rs index 9b496c416..ff8c11ed3 100644 --- a/src/mkfifo/mkfifo.rs +++ b/src/mkfifo/mkfifo.rs @@ -12,7 +12,7 @@ extern crate getopts; extern crate libc; -use libc::funcs::posix88::stat_::mkfifo; +use libc::mkfifo; use std::ffi::CString; use std::io::{Error, Write}; @@ -77,3 +77,8 @@ Create a FIFO with the given name.", NAME, VERSION); exit_status } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/mv/Cargo.toml b/src/mv/Cargo.toml index a9e89f11d..5a3a1cf03 100644 --- a/src/mv/Cargo.toml +++ b/src/mv/Cargo.toml @@ -10,3 +10,9 @@ path = "mv.rs" [dependencies] getopts = "*" libc = "*" + +[dev-dependencies] +time = "*" +[[bin]] +name="mv" +path="mv.rs" diff --git a/src/mv/deps.mk b/src/mv/deps.mk deleted file mode 100644 index 0e162f8f0..000000000 --- a/src/mv/deps.mk +++ /dev/null @@ -1 +0,0 @@ -DEPLIBS += kernel32 winapi filetime time diff --git a/src/mv/mv.rs b/src/mv/mv.rs index f8317ccd9..2ce69b256 100644 --- a/src/mv/mv.rs +++ b/src/mv/mv.rs @@ -356,3 +356,8 @@ fn existing_backup_path(path: &PathBuf, suffix: &String) -> PathBuf { } simple_backup_path(path, suffix) } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/nice/Cargo.toml b/src/nice/Cargo.toml index 812e0f61b..38bf0a322 100644 --- a/src/nice/Cargo.toml +++ b/src/nice/Cargo.toml @@ -10,3 +10,7 @@ path = "nice.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="nice" +path="nice.rs" diff --git a/src/nice/nice.rs b/src/nice/nice.rs index d5e13576d..2b4e9285b 100644 --- a/src/nice/nice.rs +++ b/src/nice/nice.rs @@ -110,3 +110,8 @@ process).", NAME, VERSION); show_error!("{}", Error::last_os_error()); if Error::last_os_error().raw_os_error().unwrap() as c_int == libc::ENOENT { 127 } else { 126 } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/nl/Cargo.toml b/src/nl/Cargo.toml index 3ca33339e..1c05d75ca 100644 --- a/src/nl/Cargo.toml +++ b/src/nl/Cargo.toml @@ -14,3 +14,7 @@ aho-corasick = "*" memchr = "*" regex = "*" regex-syntax = "*" + +[[bin]] +name="nl" +path="nl.rs" diff --git a/src/nl/deps.mk b/src/nl/deps.mk deleted file mode 100644 index 78a05f8b6..000000000 --- a/src/nl/deps.mk +++ /dev/null @@ -1 +0,0 @@ -DEPLIBS += aho-corasick memchr regex regex-syntax diff --git a/src/nl/nl.rs b/src/nl/nl.rs index b6048d32d..7d5a3a8e9 100644 --- a/src/nl/nl.rs +++ b/src/nl/nl.rs @@ -328,3 +328,8 @@ fn print_usage(opts: &getopts::Options) { fn version() { println!("{} {}", NAME, VERSION); } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/nohup/Cargo.toml b/src/nohup/Cargo.toml index e4d916481..70766b16b 100644 --- a/src/nohup/Cargo.toml +++ b/src/nohup/Cargo.toml @@ -10,3 +10,7 @@ path = "nohup.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="nohup" +path="nohup.rs" diff --git a/src/nohup/nohup.rs b/src/nohup/nohup.rs index 304776d5a..fb7958faa 100644 --- a/src/nohup/nohup.rs +++ b/src/nohup/nohup.rs @@ -12,17 +12,14 @@ extern crate getopts; extern crate libc; -use libc::c_char; -use libc::funcs::posix01::signal::signal; -use libc::funcs::posix88::unistd::{dup2, execvp, isatty}; -use libc::consts::os::posix01::SIG_IGN; -use libc::consts::os::posix88::SIGHUP; -use std::env; +use libc::{c_char, signal, dup2, execvp, isatty}; +use libc::{SIG_IGN, SIGHUP}; use std::ffi::CString; use std::fs::{File, OpenOptions}; use std::io::{Error, Write}; use std::os::unix::prelude::*; use std::path::{Path, PathBuf}; +use std::env; #[path = "../common/util.rs"] #[macro_use] mod util; #[path = "../common/c_types.rs"] mod c_types; @@ -147,3 +144,8 @@ If standard error is terminal, it'll be redirected to stdout.", NAME, VERSION); print!("{}", opts.usage(&msg)); } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/nproc/Cargo.toml b/src/nproc/Cargo.toml index 289086eb5..d0c1ea9be 100644 --- a/src/nproc/Cargo.toml +++ b/src/nproc/Cargo.toml @@ -11,3 +11,7 @@ path = "nproc.rs" getopts = "*" libc = "*" num_cpus = "*" + +[[bin]] +name="nproc" +path="nproc.rs" diff --git a/src/nproc/deps.mk b/src/nproc/deps.mk deleted file mode 100644 index 8bd1a6c62..000000000 --- a/src/nproc/deps.mk +++ /dev/null @@ -1 +0,0 @@ -DEPLIBS += num_cpus diff --git a/src/nproc/nproc.rs b/src/nproc/nproc.rs index 037d2a3e7..0e64c8500 100644 --- a/src/nproc/nproc.rs +++ b/src/nproc/nproc.rs @@ -12,8 +12,8 @@ extern crate getopts; extern crate num_cpus; -use std::env; use std::io::Write; +use std::env; static NAME : &'static str = "nproc"; static VERSION : &'static str = "0.0.0"; @@ -85,3 +85,8 @@ Print the number of cores available to the current process.", NAME, VERSION); println!("{}", cores); 0 } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/od/Cargo.toml b/src/od/Cargo.toml index e6e1d7183..e3fff21b0 100644 --- a/src/od/Cargo.toml +++ b/src/od/Cargo.toml @@ -10,3 +10,7 @@ path = "od.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="od" +path="od.rs" diff --git a/src/od/od.rs b/src/od/od.rs index da9295855..471abf859 100644 --- a/src/od/od.rs +++ b/src/od/od.rs @@ -56,12 +56,12 @@ pub fn uumain(args: Vec) -> i32 { None => { panic!("Need fname for now") ; } }; - main(&input_offset_base, &fname); + odfunc(&input_offset_base, &fname); 0 } -fn main(input_offset_base: &Radix, fname: &str) { +fn odfunc(input_offset_base: &Radix, fname: &str) { let mut f = match File::open(Path::new(fname)) { Ok(f) => f, Err(e) => panic!("file error: {}", e) @@ -124,3 +124,8 @@ fn print_with_radix(r: &Radix, x: usize) { Radix::Binary => print!("{:07b}", x) } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/paste/Cargo.toml b/src/paste/Cargo.toml index 9800ef127..95f992752 100644 --- a/src/paste/Cargo.toml +++ b/src/paste/Cargo.toml @@ -10,3 +10,7 @@ path = "paste.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="paste" +path="paste.rs" diff --git a/src/paste/paste.rs b/src/paste/paste.rs index 6a8592138..8b6c15f3c 100644 --- a/src/paste/paste.rs +++ b/src/paste/paste.rs @@ -128,3 +128,8 @@ fn unescape(s: String) -> String { .replace("\\\\", "\\") .replace("\\", "") } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/printenv/Cargo.toml b/src/printenv/Cargo.toml index 166816d5c..a3ee2009e 100644 --- a/src/printenv/Cargo.toml +++ b/src/printenv/Cargo.toml @@ -10,3 +10,7 @@ path = "printenv.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="printenv" +path="printenv.rs" diff --git a/src/printenv/printenv.rs b/src/printenv/printenv.rs index d895449f9..0995bea92 100644 --- a/src/printenv/printenv.rs +++ b/src/printenv/printenv.rs @@ -14,8 +14,8 @@ extern crate getopts; extern crate libc; -use std::env; use std::io::Write; +use std::env; #[path = "../common/util.rs"] #[macro_use] @@ -76,3 +76,8 @@ pub fn exec(args: Vec, separator: &str) { } } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/ptx/Cargo.toml b/src/ptx/Cargo.toml index 65f0cc7b7..9d43268c6 100644 --- a/src/ptx/Cargo.toml +++ b/src/ptx/Cargo.toml @@ -14,3 +14,7 @@ aho-corasick = "*" memchr = "*" regex-syntax = "*" regex = "*" + +[[bin]] +name="ptx" +path="ptx.rs" diff --git a/src/ptx/deps.mk b/src/ptx/deps.mk deleted file mode 100644 index 78a05f8b6..000000000 --- a/src/ptx/deps.mk +++ /dev/null @@ -1 +0,0 @@ -DEPLIBS += aho-corasick memchr regex regex-syntax diff --git a/src/ptx/ptx.rs b/src/ptx/ptx.rs index 0569d130b..d766e88ae 100644 --- a/src/ptx/ptx.rs +++ b/src/ptx/ptx.rs @@ -562,3 +562,8 @@ pub fn uumain(args: Vec) -> i32 { write_traditional_output(&config, &file_map, &word_set, &output_file); 0 } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/pwd/Cargo.toml b/src/pwd/Cargo.toml index 9b4c9afbd..cdf4c7f48 100644 --- a/src/pwd/Cargo.toml +++ b/src/pwd/Cargo.toml @@ -10,3 +10,7 @@ path = "pwd.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="pwd" +path="pwd.rs" diff --git a/src/pwd/pwd.rs b/src/pwd/pwd.rs index 3205e0c32..ac645626e 100644 --- a/src/pwd/pwd.rs +++ b/src/pwd/pwd.rs @@ -12,8 +12,8 @@ extern crate getopts; extern crate libc; -use std::env; use std::io::Write; +use std::env; #[path = "../common/util.rs"] #[macro_use] @@ -51,3 +51,8 @@ Print the full filename of the current working directory.", NAME, VERSION); 0 } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/readlink/Cargo.toml b/src/readlink/Cargo.toml index 42e5db253..d46dd5954 100644 --- a/src/readlink/Cargo.toml +++ b/src/readlink/Cargo.toml @@ -10,3 +10,7 @@ path = "readlink.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="readlink" +path="readlink.rs" diff --git a/src/readlink/readlink.rs b/src/readlink/readlink.rs index 58640b97d..da65d5056 100644 --- a/src/readlink/readlink.rs +++ b/src/readlink/readlink.rs @@ -138,3 +138,8 @@ fn show_usage(opts: &getopts::Options) { print!("Print value of a symbolic link or canonical file name"); print!("{}", opts.usage("")); } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/realpath/Cargo.toml b/src/realpath/Cargo.toml index b481bf0a0..329415b86 100644 --- a/src/realpath/Cargo.toml +++ b/src/realpath/Cargo.toml @@ -10,3 +10,7 @@ path = "realpath.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="realpath" +path="realpath.rs" diff --git a/src/realpath/realpath.rs b/src/realpath/realpath.rs index 62b1f951b..7a2c9d325 100644 --- a/src/realpath/realpath.rs +++ b/src/realpath/realpath.rs @@ -140,3 +140,8 @@ fn show_usage(opts: &getopts::Options) { Each resolved FILENAME will be written to the standard output, one per line.") ); } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/relpath/Cargo.toml b/src/relpath/Cargo.toml index c45a18deb..11efcca2c 100644 --- a/src/relpath/Cargo.toml +++ b/src/relpath/Cargo.toml @@ -10,3 +10,7 @@ path = "relpath.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="relpath" +path="relpath.rs" diff --git a/src/relpath/relpath.rs b/src/relpath/relpath.rs index 1f4cebcbc..c0c01185f 100644 --- a/src/relpath/relpath.rs +++ b/src/relpath/relpath.rs @@ -105,3 +105,8 @@ fn show_usage(opts: &getopts::Options) { If FROM path is omitted, current working dir will be used.") ); } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/rm/Cargo.toml b/src/rm/Cargo.toml index 953e7caf0..dc4128ec3 100644 --- a/src/rm/Cargo.toml +++ b/src/rm/Cargo.toml @@ -10,3 +10,7 @@ path = "rm.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="rm" +path="rm.rs" diff --git a/src/rm/rm.rs b/src/rm/rm.rs index f8a9c8d44..34e1e1e42 100644 --- a/src/rm/rm.rs +++ b/src/rm/rm.rs @@ -290,3 +290,8 @@ fn prompt(msg: &str) -> bool { _ => false, } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/rmdir/Cargo.toml b/src/rmdir/Cargo.toml index ec6dc3639..667643385 100644 --- a/src/rmdir/Cargo.toml +++ b/src/rmdir/Cargo.toml @@ -10,3 +10,7 @@ path = "rmdir.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="rmdir" +path="rmdir.rs" diff --git a/src/rmdir/rmdir.rs b/src/rmdir/rmdir.rs index 56df54c3c..68ddf76e3 100644 --- a/src/rmdir/rmdir.rs +++ b/src/rmdir/rmdir.rs @@ -124,3 +124,8 @@ fn remove_dir(path: &Path, ignore: bool, verbose: bool) -> Result<(), i32> { r } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/seq/Cargo.toml b/src/seq/Cargo.toml index 4b56530a8..dc3634507 100644 --- a/src/seq/Cargo.toml +++ b/src/seq/Cargo.toml @@ -10,3 +10,7 @@ path = "seq.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="seq" +path="seq.rs" diff --git a/src/seq/seq.rs b/src/seq/seq.rs index 88fcb2e71..e28714633 100644 --- a/src/seq/seq.rs +++ b/src/seq/seq.rs @@ -258,3 +258,8 @@ fn print_seq(first: f64, step: f64, last: f64, largest_dec: usize, separator: St } pipe_flush!(); } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/shuf/Cargo.toml b/src/shuf/Cargo.toml index 81101d39f..944d4ddd9 100644 --- a/src/shuf/Cargo.toml +++ b/src/shuf/Cargo.toml @@ -11,3 +11,7 @@ path = "shuf.rs" getopts = "*" libc = "*" rand = "*" + +[[bin]] +name="shuf" +path="shuf.rs" diff --git a/src/shuf/deps.mk b/src/shuf/deps.mk deleted file mode 100644 index ea0f8a6b8..000000000 --- a/src/shuf/deps.mk +++ /dev/null @@ -1 +0,0 @@ -DEPLIBS += rand diff --git a/src/shuf/shuf.rs b/src/shuf/shuf.rs index b4ea0ebbe..34ca1614e 100644 --- a/src/shuf/shuf.rs +++ b/src/shuf/shuf.rs @@ -267,3 +267,8 @@ impl WrappedRng { } } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/sleep/Cargo.toml b/src/sleep/Cargo.toml index 6c29d728d..4a14913ce 100644 --- a/src/sleep/Cargo.toml +++ b/src/sleep/Cargo.toml @@ -10,3 +10,7 @@ path = "sleep.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="sleep" +path="sleep.rs" diff --git a/src/sleep/sleep.rs b/src/sleep/sleep.rs index 70abc233e..545ba6600 100644 --- a/src/sleep/sleep.rs +++ b/src/sleep/sleep.rs @@ -13,7 +13,8 @@ extern crate getopts; extern crate libc; use std::io::Write; -use std::thread::sleep_ms; +use std::thread::{self}; +use std::time::Duration; use std::u32::MAX as U32_MAX; #[path = "../common/util.rs"] @@ -75,7 +76,12 @@ fn sleep(args: Vec) { let sleep_dur = if sleep_time > (U32_MAX as f64) { U32_MAX } else { - (1000.0 * sleep_time) as u32 + (1000000.0 * sleep_time) as u32 }; - sleep_ms(sleep_dur); + thread::sleep(Duration::new(0, sleep_dur)); +} + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); } diff --git a/src/sort/Cargo.toml b/src/sort/Cargo.toml index c88e0b7fb..c0c9290a9 100644 --- a/src/sort/Cargo.toml +++ b/src/sort/Cargo.toml @@ -10,3 +10,7 @@ path = "sort.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="sort" +path="sort.rs" diff --git a/src/sort/sort.rs b/src/sort/sort.rs index 03b830593..67d72b8fe 100644 --- a/src/sort/sort.rs +++ b/src/sort/sort.rs @@ -14,9 +14,8 @@ extern crate getopts; extern crate libc; -use libc::consts::os::posix88::STDIN_FILENO; -use libc::funcs::posix88::unistd::isatty; -use libc::types::os::arch::c95::c_int; +use libc::STDIN_FILENO; +use libc::{c_int, isatty}; use std::cmp::Ordering; use std::fs::File; use std::io::{BufRead, BufReader, Read, stdin, Write}; @@ -208,3 +207,8 @@ fn open<'a>(path: &str) -> Option<(Box, bool)> { }, } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/split/Cargo.toml b/src/split/Cargo.toml index 3c0d0de3b..7c6e1b579 100644 --- a/src/split/Cargo.toml +++ b/src/split/Cargo.toml @@ -10,3 +10,7 @@ path = "split.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="split" +path="split.rs" diff --git a/src/split/deps.mk b/src/split/deps.mk deleted file mode 100644 index 62b0140cc..000000000 --- a/src/split/deps.mk +++ /dev/null @@ -1 +0,0 @@ -DEPLIBS += aho-corasick memchr rand regex regex-syntax diff --git a/src/split/split.rs b/src/split/split.rs index 08d57cd18..dfd320789 100644 --- a/src/split/split.rs +++ b/src/split/split.rs @@ -315,3 +315,8 @@ fn split(settings: &Settings) -> i32 { } 0 } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/stdbuf/Cargo.toml b/src/stdbuf/Cargo.toml new file mode 100644 index 000000000..c21aa55f5 --- /dev/null +++ b/src/stdbuf/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "stdbuf" +version = "0.0.1" +authors = [] + +[lib] +name = "stdbuf" +path = "stdbuf.rs" + +[dependencies] +getopts = "*" +libc = "*" + +[[bin]] +name="stdbuf" +path="stdbuf.rs" diff --git a/src/stdbuf/stdbuf.rs b/src/stdbuf/stdbuf.rs index ecb30fa76..300ffd83e 100644 --- a/src/stdbuf/stdbuf.rs +++ b/src/stdbuf/stdbuf.rs @@ -13,7 +13,6 @@ extern crate getopts; extern crate libc; use getopts::{Matches, Options}; -use std::env; use std::io::{self, Write}; use std::os::unix::process::ExitStatusExt; use std::path::PathBuf; @@ -192,7 +191,7 @@ fn set_command_env(command: &mut Command, buffer_name: &str, buffer_type: Buffer } fn exe_path() -> io::Result { - let exe_path = try!(env::current_exe()); + let exe_path = try!(std::env::current_exe()); let absolute_path = try!(canonicalize(exe_path, CanonicalizeMode::Normal)); Ok(match absolute_path.parent() { Some(p) => p.to_path_buf(), @@ -270,3 +269,8 @@ pub fn uumain(args: Vec) -> i32 { Err(e) => crash!(1, "{}", e) }; } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/sum/Cargo.toml b/src/sum/Cargo.toml index 7655fd221..f10bc5745 100644 --- a/src/sum/Cargo.toml +++ b/src/sum/Cargo.toml @@ -10,3 +10,7 @@ path = "sum.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="sum" +path="sum.rs" diff --git a/src/sum/sum.rs b/src/sum/sum.rs index 75f25adee..690ce1198 100644 --- a/src/sum/sum.rs +++ b/src/sum/sum.rs @@ -138,3 +138,8 @@ Checksum and count the blocks in a file.", NAME, VERSION); 0 } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/sync/Cargo.toml b/src/sync/Cargo.toml index 2c17e5550..5e58cb359 100644 --- a/src/sync/Cargo.toml +++ b/src/sync/Cargo.toml @@ -10,3 +10,7 @@ path = "sync.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="sync" +path="sync.rs" diff --git a/src/sync/deps.mk b/src/sync/deps.mk deleted file mode 100644 index bd85e154d..000000000 --- a/src/sync/deps.mk +++ /dev/null @@ -1 +0,0 @@ -DEPLIBS += winapi kernel32 diff --git a/src/sync/sync.rs b/src/sync/sync.rs index 3f3834774..a0dfccf69 100644 --- a/src/sync/sync.rs +++ b/src/sync/sync.rs @@ -144,3 +144,8 @@ fn sync() -> isize { platform::do_sync() } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/tac/Cargo.toml b/src/tac/Cargo.toml index 2a4dd498f..aa3b3d563 100644 --- a/src/tac/Cargo.toml +++ b/src/tac/Cargo.toml @@ -10,3 +10,7 @@ path = "tac.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="tac" +path="tac.rs" diff --git a/src/tac/tac.rs b/src/tac/tac.rs index 995d5c2d7..49997fa57 100644 --- a/src/tac/tac.rs +++ b/src/tac/tac.rs @@ -147,3 +147,8 @@ fn show_line(out: &mut Stdout, sep: &[u8], dat: &[u8], before: bool) { out.write_all(sep).unwrap_or_else(|e| crash!(1, "failed to write to stdout: {}", e)); } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/tail/Cargo.toml b/src/tail/Cargo.toml index beac774b1..bc3e0e2f6 100644 --- a/src/tail/Cargo.toml +++ b/src/tail/Cargo.toml @@ -10,3 +10,7 @@ path = "tail.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="tail" +path="tail.rs" diff --git a/src/tail/tail.rs b/src/tail/tail.rs index 8b64760a5..45d91ec33 100644 --- a/src/tail/tail.rs +++ b/src/tail/tail.rs @@ -17,7 +17,8 @@ use std::fs::File; use std::io::{BufRead, BufReader, Read, stdin, stdout, Write}; use std::path::Path; use std::str::from_utf8; -use std::thread::sleep_ms; +use std::thread::sleep; +use std::time::Duration; #[path = "../common/util.rs"] #[macro_use] @@ -273,7 +274,7 @@ fn tail(reader: &mut BufReader, mut line_count: usize, mut byte_coun // if we follow the file, sleep a bit and print the rest if the file has grown. while follow { - sleep_ms(sleep_msec); + sleep(Duration::new(0, sleep_msec*1000)); for io_line in reader.lines() { match io_line { Ok(line) => print!("{}", line), @@ -298,3 +299,8 @@ fn print_string(_: &mut T, s: &String) { fn version () { println!("{} {}", NAME, VERSION); } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/tee/Cargo.toml b/src/tee/Cargo.toml index d91409f52..f30515dbe 100644 --- a/src/tee/Cargo.toml +++ b/src/tee/Cargo.toml @@ -10,3 +10,7 @@ path = "tee.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="tee" +path="tee.rs" diff --git a/src/tee/tee.rs b/src/tee/tee.rs index 52279708f..ba712670e 100644 --- a/src/tee/tee.rs +++ b/src/tee/tee.rs @@ -172,3 +172,8 @@ fn warn(message: &str) -> Error { eprintln!("{}: {}", NAME, message); Error::new(ErrorKind::Other, format!("{}: {}", NAME, message)) } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/test/Cargo.toml b/src/test/Cargo.toml index 38acc688a..17bf8e03e 100644 --- a/src/test/Cargo.toml +++ b/src/test/Cargo.toml @@ -1,12 +1,16 @@ [package] -name = "test" +name = "test_uu" version = "0.0.1" authors = [] [lib] -name = "test" +name = "test_uu" path = "test.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="test" +path="test.rs" diff --git a/src/test/test.rs b/src/test/test.rs index 7cd446e69..5e0c1d685 100644 --- a/src/test/test.rs +++ b/src/test/test.rs @@ -1,4 +1,4 @@ -#![crate_name = "test"] +#![crate_name = "test_uu"] /* * This file is part of the uutils coreutils package. @@ -406,3 +406,8 @@ fn path(path: &[u8], cond: PathCondition) -> bool { PathCondition::Executable => false, // TODO } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/timeout/Cargo.toml b/src/timeout/Cargo.toml index 18d3c3ba2..1dac40526 100644 --- a/src/timeout/Cargo.toml +++ b/src/timeout/Cargo.toml @@ -11,3 +11,7 @@ path = "timeout.rs" getopts = "*" libc = "*" time = "*" + +[[bin]] +name="timeout" +path="timeout.rs" diff --git a/src/timeout/deps.mk b/src/timeout/deps.mk deleted file mode 100644 index b6534caec..000000000 --- a/src/timeout/deps.mk +++ /dev/null @@ -1 +0,0 @@ -DEPLIBS += time diff --git a/src/timeout/timeout.rs b/src/timeout/timeout.rs index 8a16c2b38..c6867076a 100644 --- a/src/timeout/timeout.rs +++ b/src/timeout/timeout.rs @@ -157,3 +157,8 @@ fn timeout(cmdname: &str, args: &[String], duration: f64, signal: usize, kill_af }, } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/touch/Cargo.toml b/src/touch/Cargo.toml index 4c2c7c509..bb9b40438 100644 --- a/src/touch/Cargo.toml +++ b/src/touch/Cargo.toml @@ -12,3 +12,7 @@ filetime = "*" getopts = "*" libc = "*" time = "*" + +[[bin]] +name="touch" +path="touch.rs" diff --git a/src/touch/deps.mk b/src/touch/deps.mk deleted file mode 100644 index 0e162f8f0..000000000 --- a/src/touch/deps.mk +++ /dev/null @@ -1 +0,0 @@ -DEPLIBS += kernel32 winapi filetime time diff --git a/src/touch/touch.rs b/src/touch/touch.rs index 9f51f9837..efee232cc 100644 --- a/src/touch/touch.rs +++ b/src/touch/touch.rs @@ -209,3 +209,8 @@ fn parse_timestamp(s: &str) -> FileTime { } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/tr/Cargo.toml b/src/tr/Cargo.toml index 0c47ab424..cbbed1673 100644 --- a/src/tr/Cargo.toml +++ b/src/tr/Cargo.toml @@ -12,3 +12,7 @@ getopts = "*" libc = "*" bit-set = "*" vec_map = "*" + +[[bin]] +name="tr" +path="tr.rs" diff --git a/src/tr/deps.mk b/src/tr/deps.mk deleted file mode 100644 index 5e9f37b70..000000000 --- a/src/tr/deps.mk +++ /dev/null @@ -1 +0,0 @@ -DEPLIBS += bit-vec bit-set vec_map diff --git a/src/tr/tr.rs b/src/tr/tr.rs index 7ec6627ff..877788691 100644 --- a/src/tr/tr.rs +++ b/src/tr/tr.rs @@ -162,3 +162,8 @@ pub fn uumain(args: Vec) -> i32 { 0 } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/true/Cargo.toml b/src/true/Cargo.toml index d5b7fe5cc..2b0154c53 100644 --- a/src/true/Cargo.toml +++ b/src/true/Cargo.toml @@ -10,3 +10,7 @@ path = "true.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="true" +path="true.rs" diff --git a/src/true/true.rs b/src/true/true.rs index 772870f54..f37b1a8eb 100644 --- a/src/true/true.rs +++ b/src/true/true.rs @@ -9,6 +9,12 @@ * file that was distributed with this source code. */ + pub fn uumain(_: Vec) -> i32 { 0 } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/truncate/Cargo.toml b/src/truncate/Cargo.toml index 2795af9fb..d36728324 100644 --- a/src/truncate/Cargo.toml +++ b/src/truncate/Cargo.toml @@ -10,3 +10,7 @@ path = "truncate.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="truncate" +path="truncate.rs" diff --git a/src/truncate/truncate.rs b/src/truncate/truncate.rs index 7cffc301b..8f0b79d84 100644 --- a/src/truncate/truncate.rs +++ b/src/truncate/truncate.rs @@ -213,3 +213,8 @@ fn parse_size(size: &str) -> (u64, TruncateMode) { } (number, mode) } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/tsort/Cargo.toml b/src/tsort/Cargo.toml index 877cf9707..12b45b748 100644 --- a/src/tsort/Cargo.toml +++ b/src/tsort/Cargo.toml @@ -10,3 +10,7 @@ path = "tsort.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="tsort" +path="tsort.rs" diff --git a/src/tsort/tsort.rs b/src/tsort/tsort.rs index 6f43aaebb..0bca10b41 100644 --- a/src/tsort/tsort.rs +++ b/src/tsort/tsort.rs @@ -194,3 +194,8 @@ impl Graph { true } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/tty/Cargo.toml b/src/tty/Cargo.toml index 40e4f8a82..699033899 100644 --- a/src/tty/Cargo.toml +++ b/src/tty/Cargo.toml @@ -10,3 +10,7 @@ path = "tty.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="tty" +path="tty.rs" diff --git a/src/tty/tty.rs b/src/tty/tty.rs index 7bac51a0f..12cbd25d9 100644 --- a/src/tty/tty.rs +++ b/src/tty/tty.rs @@ -81,3 +81,8 @@ pub fn uumain(args: Vec) -> i32 { 0 } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/uname/Cargo.toml b/src/uname/Cargo.toml index 4f10bc75a..c6d381cf7 100644 --- a/src/uname/Cargo.toml +++ b/src/uname/Cargo.toml @@ -10,3 +10,7 @@ path = "uname.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="uname" +path="uname.rs" diff --git a/src/uname/uname.rs b/src/uname/uname.rs index 7b5700f85..e8a7c075f 100644 --- a/src/uname/uname.rs +++ b/src/uname/uname.rs @@ -106,3 +106,8 @@ pub fn uumain(args: Vec) -> i32 { 0 } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/unexpand/Cargo.toml b/src/unexpand/Cargo.toml index 4e631f138..01612c5d5 100644 --- a/src/unexpand/Cargo.toml +++ b/src/unexpand/Cargo.toml @@ -11,3 +11,7 @@ path = "unexpand.rs" getopts = "*" libc = "*" unicode-width = "*" + +[[bin]] +name="unexpand" +path="unexpand.rs" diff --git a/src/unexpand/deps.mk b/src/unexpand/deps.mk deleted file mode 100644 index fb8005c0c..000000000 --- a/src/unexpand/deps.mk +++ /dev/null @@ -1 +0,0 @@ -DEPLIBS += unicode-width diff --git a/src/unexpand/unexpand.rs b/src/unexpand/unexpand.rs index af138dcef..481aa84e7 100644 --- a/src/unexpand/unexpand.rs +++ b/src/unexpand/unexpand.rs @@ -281,3 +281,8 @@ fn unexpand(options: Options) { } pipe_flush!(output); } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/uniq/Cargo.toml b/src/uniq/Cargo.toml index 81245beb1..a1997a355 100644 --- a/src/uniq/Cargo.toml +++ b/src/uniq/Cargo.toml @@ -10,3 +10,7 @@ path = "uniq.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="uniq" +path="uniq.rs" diff --git a/src/uniq/uniq.rs b/src/uniq/uniq.rs index b70b0881a..c042a5948 100644 --- a/src/uniq/uniq.rs +++ b/src/uniq/uniq.rs @@ -240,3 +240,8 @@ fn open_output_file(out_file_name: String) -> BufWriter> { }; BufWriter::new(out_file) } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/unlink/Cargo.toml b/src/unlink/Cargo.toml index 11c4a5a33..bb9b0ef94 100644 --- a/src/unlink/Cargo.toml +++ b/src/unlink/Cargo.toml @@ -10,3 +10,7 @@ path = "unlink.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="unlink" +path="unlink.rs" diff --git a/src/unlink/unlink.rs b/src/unlink/unlink.rs index 1c9a5e02d..f05eb7537 100644 --- a/src/unlink/unlink.rs +++ b/src/unlink/unlink.rs @@ -15,11 +15,8 @@ extern crate getopts; extern crate libc; use getopts::Options; -use libc::consts::os::posix88::{S_IFMT, S_IFLNK, S_IFREG}; -use libc::funcs::posix01::stat_::lstat; -use libc::funcs::posix88::unistd::unlink; -use libc::types::os::arch::c95::c_char; -use libc::types::os::arch::posix01::stat; +use libc::{S_IFMT, S_IFLNK, S_IFREG}; +use libc::{lstat, unlink, c_char, stat}; use std::io::{Error, ErrorKind, Write}; use std::mem::uninitialized; @@ -94,3 +91,8 @@ pub fn uumain(args: Vec) -> i32 { 0 } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/uptime/Cargo.toml b/src/uptime/Cargo.toml index 9572f295f..baf9f9d16 100644 --- a/src/uptime/Cargo.toml +++ b/src/uptime/Cargo.toml @@ -11,3 +11,7 @@ path = "uptime.rs" getopts = "*" libc = "*" time = "*" + +[[bin]] +name="uptime" +path="uptime.rs" diff --git a/src/uptime/deps.mk b/src/uptime/deps.mk deleted file mode 100644 index b6534caec..000000000 --- a/src/uptime/deps.mk +++ /dev/null @@ -1 +0,0 @@ -DEPLIBS += time diff --git a/src/uptime/uptime.rs b/src/uptime/uptime.rs index 7b3730ef5..63e1d47e1 100644 --- a/src/uptime/uptime.rs +++ b/src/uptime/uptime.rs @@ -205,3 +205,8 @@ fn print_uptime(upsecs: i64) { print!("up {:2}:{:02}, ", uphours, upmins); } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/users/Cargo.toml b/src/users/Cargo.toml index ce7cea1f5..2ffc7148d 100644 --- a/src/users/Cargo.toml +++ b/src/users/Cargo.toml @@ -10,3 +10,7 @@ path = "users.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="users" +path="users.rs" diff --git a/src/users/users.rs b/src/users/users.rs index d46092f8b..7832208aa 100644 --- a/src/users/users.rs +++ b/src/users/users.rs @@ -120,3 +120,8 @@ fn exec(filename: &str) { println!("{}", users.join(" ")); } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/uutils/uutils.rs b/src/uutils/uutils.rs index 934acede4..45a5353e7 100644 --- a/src/uutils/uutils.rs +++ b/src/uutils/uutils.rs @@ -9,21 +9,23 @@ * file that was distributed with this source code. */ -@CRATES@ +include!(concat!(env!("OUT_DIR"), "/uutils_crates.rs")); -use std::env; use std::collections::hash_map::HashMap; use std::path::Path; +use std::env; static NAME: &'static str = "uutils"; -static VERSION: &'static str = "1.0.0"; +static VERSION: &'static str = "0.0.1"; -type UtilityMap = HashMap<&'static str, fn(Vec) -> i32>; +include!(concat!(env!("OUT_DIR"), "/uutils_map.rs")); -fn util_map() -> UtilityMap { - let mut map: UtilityMap = HashMap::new(); - @UTIL_MAP@ - map +fn name_sub(util_name: &str) -> &str { + match util_name { + "test" => "test_uu", + "test_uu" => "test", + x @ _ => x + } } fn usage(cmap: &UtilityMap) { @@ -32,7 +34,7 @@ fn usage(cmap: &UtilityMap) { println!("Usage:"); println!(" {} [util [arguments...]]\n", NAME); println!("Currently defined functions:"); - let mut utils: Vec<&str> = cmap.keys().map(|&s| s).collect(); + let mut utils: Vec<&str> = cmap.keys().map(|&s| name_sub(s)).collect(); utils.sort(); for util in utils.iter() { println!("\t{}", util); @@ -70,7 +72,7 @@ fn main() { args.remove(0); let util = &args[0][..]; - match umap.get(util) { + match umap.get(name_sub(util)) { Some(&uumain) => { std::process::exit(uumain(args.clone())); } @@ -79,7 +81,7 @@ fn main() { // see if they want help on a specific util if args.len() >= 2 { let util = &args[1][..]; - match umap.get(util) { + match umap.get(name_sub(util)) { Some(&uumain) => { std::process::exit(uumain(vec![util.to_string(), "--help".to_string()])); } diff --git a/src/uutils/uutils_cargo.rs b/src/uutils/uutils_cargo.rs deleted file mode 100644 index 275459147..000000000 --- a/src/uutils/uutils_cargo.rs +++ /dev/null @@ -1,99 +0,0 @@ -#![crate_name = "uutils"] - -/* - * This file is part of the uutils coreutils package. - * - * (c) Michael Gehring - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -include!(concat!(env!("OUT_DIR"), "/uutils_crates.rs")); - -use std::env; -use std::collections::hash_map::HashMap; -use std::path::Path; - -static NAME: &'static str = "uutils"; -static VERSION: &'static str = "0.0.1"; - -include!(concat!(env!("OUT_DIR"), "/uutils_map.rs")); - -fn usage(cmap: &UtilityMap) { - println!("{} {}", NAME, VERSION); - println!(""); - println!("Usage:"); - println!(" {} [util [arguments...]]\n", NAME); - println!("Currently defined functions:"); - let mut utils: Vec<&str> = cmap.keys().map(|&s| s).collect(); - utils.sort(); - for util in utils.iter() { - println!("\t{}", util); - } -} - -fn main() { - let umap = util_map(); - let mut args : Vec = env::args().collect(); - - // try binary name as util name. - let args0 = args[0].clone(); - let binary = Path::new(&args0[..]); - let binary_as_util = binary.file_name().unwrap().to_str().unwrap(); - - match umap.get(binary_as_util) { - Some(&uumain) => { - std::process::exit(uumain(args)); - } - None => (), - } - - if binary_as_util.ends_with("uutils") || binary_as_util.starts_with("uutils") || - binary_as_util.ends_with("busybox") || binary_as_util.starts_with("busybox") { - // uutils can be called as either "uutils", "busybox" - // "uutils-suffix" or "busybox-suffix". Not sure - // what busybox uses the -suffix pattern for. - } else { - println!("{}: applet not found", binary_as_util); - std::process::exit(1); - } - - // try first arg as util name. - if args.len() >= 2 { - args.remove(0); - let util = &args[0][..]; - - match umap.get(util) { - Some(&uumain) => { - std::process::exit(uumain(args.clone())); - } - None => { - if &args[0][..] == "--help" { - // see if they want help on a specific util - if args.len() >= 2 { - let util = &args[1][..]; - match umap.get(util) { - Some(&uumain) => { - std::process::exit(uumain(vec![util.to_string(), "--help".to_string()])); - } - None => { - println!("{}: applet not found", util); - std::process::exit(1); - } - } - } - usage(&umap); - std::process::exit(0); - } else { - println!("{}: applet not found", util); - std::process::exit(1); - } - } - } - } else { - // no arguments provided - usage(&umap); - std::process::exit(0); - } -} diff --git a/src/wc/Cargo.toml b/src/wc/Cargo.toml index cb46772b6..235b46d11 100644 --- a/src/wc/Cargo.toml +++ b/src/wc/Cargo.toml @@ -10,3 +10,7 @@ path = "wc.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="wc" +path="wc.rs" diff --git a/src/wc/wc.rs b/src/wc/wc.rs index a4215b88c..9160b1c60 100644 --- a/src/wc/wc.rs +++ b/src/wc/wc.rs @@ -282,3 +282,8 @@ fn open(path: &str) -> StdResult>, i32> { } } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/whoami/Cargo.toml b/src/whoami/Cargo.toml index 91ee10c24..c5036711c 100644 --- a/src/whoami/Cargo.toml +++ b/src/whoami/Cargo.toml @@ -10,3 +10,7 @@ path = "whoami.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="whoami" +path="whoami.rs" diff --git a/src/whoami/deps.mk b/src/whoami/deps.mk deleted file mode 100644 index dab27f417..000000000 --- a/src/whoami/deps.mk +++ /dev/null @@ -1 +0,0 @@ -DEPLIBS += winapi advapi32 kernel32 diff --git a/src/whoami/whoami.rs b/src/whoami/whoami.rs index fbcf90f27..14325b537 100644 --- a/src/whoami/whoami.rs +++ b/src/whoami/whoami.rs @@ -63,3 +63,8 @@ pub fn exec() { } } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/src/yes/Cargo.toml b/src/yes/Cargo.toml index e5280f83e..36d86854d 100644 --- a/src/yes/Cargo.toml +++ b/src/yes/Cargo.toml @@ -10,3 +10,7 @@ path = "yes.rs" [dependencies] getopts = "*" libc = "*" + +[[bin]] +name="yes" +path="yes.rs" diff --git a/src/yes/yes.rs b/src/yes/yes.rs index 52af0f53a..bc492095a 100644 --- a/src/yes/yes.rs +++ b/src/yes/yes.rs @@ -61,3 +61,8 @@ pub fn uumain(args: Vec) -> i32 { pub fn exec(string: &str) { while pipe_println!("{}", string) { } } + +#[allow(dead_code)] +fn main() { + std::process::exit(uumain(std::env::args().collect())); +} diff --git a/test/base64.rs b/test/base64.rs deleted file mode 100644 index 106a42de5..000000000 --- a/test/base64.rs +++ /dev/null @@ -1,62 +0,0 @@ -use std::process::Command; -use util::*; - -static PROGNAME: &'static str = "./base64"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn test_encode() { - let input = "hello, world!"; - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd, input.as_bytes()); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, "aGVsbG8sIHdvcmxkIQ==\n"); -} - -#[test] -fn test_decode() { - let input = "aGVsbG8sIHdvcmxkIQ=="; - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.arg("-d"), input.as_bytes()); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, "hello, world!"); -} - -#[test] -fn test_garbage() { - let input = "aGVsbG8sIHdvcmxkIQ==\0"; - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.arg("-d"), input.as_bytes()); - - assert!(!result.success); - assert_eq!(result.stderr, "base64: error: invalid character (Invalid character '0' at position 20)\n"); -} - -#[test] -fn test_ignore_garbage() { - let input = "aGVsbG8sIHdvcmxkIQ==\0"; - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.arg("-d").arg("-i"), input.as_bytes()); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, "hello, world!"); -} - -#[test] -fn test_wrap() { - let input = "The quick brown fox jumps over the lazy dog."; - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.arg("-w").arg("20"), input.as_bytes()); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, "VGhlIHF1aWNrIGJyb3du\nIGZveCBqdW1wcyBvdmVy\nIHRoZSBsYXp5IGRvZy4=\n"); -} diff --git a/test/basename.rs b/test/basename.rs deleted file mode 100644 index 6ecf224c0..000000000 --- a/test/basename.rs +++ /dev/null @@ -1,54 +0,0 @@ -use std::process::Command; -use std::str; - -static PROGNAME: &'static str = "./basename"; - -#[test] -fn test_directory() { - let dir = "/root/alpha/beta/gamma/delta/epsilon/omega/"; - let po = Command::new(PROGNAME) - .arg(dir) - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right(); - assert_eq!(out, "omega"); -} - -#[test] -fn test_file() { - let file = "/etc/passwd"; - let po = Command::new(PROGNAME) - .arg(file) - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right(); - assert_eq!(out, "passwd"); -} - -#[test] -fn test_remove_suffix() { - let path = "/usr/local/bin/reallylongexecutable.exe"; - let po = Command::new(PROGNAME) - .arg(path) - .arg(".exe") - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right(); - assert_eq!(out, "reallylongexecutable"); -} - -#[test] -fn test_dont_remove_suffix() { - let path = "/foo/bar/baz"; - let po = Command::new(PROGNAME) - .arg(path) - .arg("baz") - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right(); - assert_eq!(out, "baz"); -} diff --git a/test/cat.rs b/test/cat.rs deleted file mode 100644 index 41fdb9eb6..000000000 --- a/test/cat.rs +++ /dev/null @@ -1,60 +0,0 @@ -use std::io::Write; -use std::process::Command; -use std::process::Stdio; -use std::str; - -static PROGNAME: &'static str = "./cat"; - -#[test] -fn test_output_multi_files_print_all_chars() { - let po = match Command::new(PROGNAME) - .arg("alpha.txt") - .arg("256.txt") - .arg("-A") - .arg("-n").output() { - - Ok(p) => p, - Err(err) => panic!("{}", err), - }; - - let out = str::from_utf8(&po.stdout[..]).unwrap(); - assert_eq!(out, - " 1\tabcde$\n 2\tfghij$\n 3\tklmno$\n 4\tpqrst$\n 5\tuvwxyz$\n 6\t^@^A^B^C^D^E^F^G^H^I$\n 7\t^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z^[^\\^]^^^_ !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~^?M-^@M-^AM-^BM-^CM-^DM-^EM-^FM-^GM-^HM-^IM-^JM-^KM-^LM-^MM-^NM-^OM-^PM-^QM-^RM-^SM-^TM-^UM-^VM-^WM-^XM-^YM-^ZM-^[M-^\\M-^]M-^^M-^_M- M-!M-\"M-#M-$M-%M-&M-\'M-(M-)M-*M-+M-,M--M-.M-/M-0M-1M-2M-3M-4M-5M-6M-7M-8M-9M-:M-;M-M-?M-@M-AM-BM-CM-DM-EM-FM-GM-HM-IM-JM-KM-LM-MM-NM-OM-PM-QM-RM-SM-TM-UM-VM-WM-XM-YM-ZM-[M-\\M-]M-^M-_M-`M-aM-bM-cM-dM-eM-fM-gM-hM-iM-jM-kM-lM-mM-nM-oM-pM-qM-rM-sM-tM-uM-vM-wM-xM-yM-zM-{M-|M-}M-~M-^?"); -} - -#[test] -fn test_stdin_squeeze() { - let mut process = Command::new(PROGNAME) - .arg("-A") - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - .unwrap_or_else(|e| panic!("{}", e)); - - process.stdin.take().unwrap_or_else(|| panic!("Could not grab child process stdin")) - .write_all("\x00\x01\x02".as_bytes()).unwrap_or_else(|e| panic!("{}", e)); - - let po = process.wait_with_output().unwrap_or_else(|e| panic!("{}", e)); - let out = str::from_utf8(&po.stdout[..]).unwrap_or_else(|e| panic!("{}", e)); - - assert_eq!(out, "^@^A^B"); -} - -#[test] -fn test_stdin_number_non_blank() { - let mut process = Command::new(PROGNAME) - .arg("-b") - .arg("-") - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - .unwrap_or_else(|e| panic!("{}", e)); - - process.stdin.take().unwrap_or_else(|| panic!("Could not grab child process stdin")) - .write_all("\na\nb\n\n\nc".as_bytes()).unwrap_or_else(|e| panic!("{}", e)); - - let po = process.wait_with_output().unwrap_or_else(|e| panic!("{}", e)); - let out = str::from_utf8(&po.stdout[..]).unwrap_or_else(|e| panic!("{}", e)); - - assert_eq!(out, "\n 1\ta\n 2\tb\n\n\n 3\tc"); -} diff --git a/test/cksum.rs b/test/cksum.rs deleted file mode 100644 index c5ecdf3be..000000000 --- a/test/cksum.rs +++ /dev/null @@ -1,39 +0,0 @@ -use std::process::Command; -use util::*; - -static PROGNAME: &'static str = "./cksum"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn test_single_file() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.arg("lorem_ipsum.txt")); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, get_file_contents("single_file.expected")); -} - -#[test] -fn test_multiple_files() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.arg("lorem_ipsum.txt").arg("alice_in_wonderland.txt")); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, get_file_contents("multiple_files.expected")); -} - -#[test] -fn test_stdin() { - let input = get_file_contents("lorem_ipsum.txt"); - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd, input); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, get_file_contents("stdin.expected")); -} diff --git a/test/common/util.rs b/test/common/util.rs deleted file mode 100644 index cb4a99c83..000000000 --- a/test/common/util.rs +++ /dev/null @@ -1,152 +0,0 @@ -#![allow(dead_code)] - -use std::env; -use std::fs::{self, File}; -use std::io::{Read, Write}; -#[cfg(unix)] -use std::os::unix::fs::symlink as symlink_file; -#[cfg(windows)] -use std::os::windows::fs::symlink_file; -use std::path::Path; -use std::process::{Command, Stdio}; -use std::str::from_utf8; - -#[macro_export] -macro_rules! assert_empty_stderr( - ($cond:expr) => ( - if $cond.stderr.len() > 0 { - panic!(format!("stderr: {}", $cond.stderr)) - } - ); -); - -pub struct CmdResult { - pub success: bool, - pub stdout: String, - pub stderr: String, -} - -pub fn run(cmd: &mut Command) -> CmdResult { - let prog = cmd.output().unwrap(); - CmdResult { - success: prog.status.success(), - stdout: from_utf8(&prog.stdout).unwrap().to_string(), - stderr: from_utf8(&prog.stderr).unwrap().to_string(), - } -} - -pub fn run_piped_stdin>(cmd: &mut Command, input: T)-> CmdResult { - let mut command = cmd - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .spawn() - .unwrap(); - - command.stdin - .take() - .unwrap_or_else(|| panic!("Could not take child process stdin")) - .write_all(input.as_ref()) - .unwrap_or_else(|e| panic!("{}", e)); - - let prog = command.wait_with_output().unwrap(); - CmdResult { - success: prog.status.success(), - stdout: from_utf8(&prog.stdout).unwrap().to_string(), - stderr: from_utf8(&prog.stderr).unwrap().to_string(), - } -} - -pub fn get_file_contents(name: &str) -> String { - let mut f = File::open(Path::new(name)).unwrap(); - let mut contents = String::new(); - let _ = f.read_to_string(&mut contents); - contents -} - -pub fn set_file_contents(name: &str, contents: &str) { - let mut f = File::open(Path::new(name)).unwrap(); - let _ = f.write(contents.as_bytes()); -} - -pub fn mkdir(dir: &str) { - fs::create_dir(Path::new(dir)).unwrap(); -} - -pub fn mkdir_all(dir: &str) { - fs::create_dir_all(Path::new(dir)).unwrap(); -} - -pub fn make_file(name: &str) -> File { - match File::create(Path::new(name)) { - Ok(f) => f, - Err(e) => panic!("{}", e) - } -} - -pub fn touch(file: &str) { - File::create(Path::new(file)).unwrap(); -} - -pub fn symlink(src: &str, dst: &str) { - symlink_file(src, dst).unwrap(); -} - -pub fn is_symlink(path: &str) -> bool { - match fs::symlink_metadata(path) { - Ok(m) => m.file_type().is_symlink(), - Err(_) => false - } -} - -pub fn resolve_link(path: &str) -> String { - match fs::read_link(path) { - Ok(p) => p.to_str().unwrap().to_owned(), - Err(_) => "".to_string() - } -} - -pub fn metadata(path: &str) -> fs::Metadata { - match fs::metadata(path) { - Ok(m) => m, - Err(e) => panic!("{}", e) - } -} - -pub fn file_exists(path: &str) -> bool { - match fs::metadata(path) { - Ok(m) => m.is_file(), - Err(_) => false - } -} - -pub fn dir_exists(path: &str) -> bool { - match fs::metadata(path) { - Ok(m) => m.is_dir(), - Err(_) => false - } -} - -pub fn cleanup(path: &'static str) { - let p = Path::new(path); - match fs::metadata(p) { - Ok(m) => if m.is_file() { - fs::remove_file(&p).unwrap(); - } else { - fs::remove_dir(&p).unwrap(); - }, - Err(_) => {} - } -} - -pub fn current_directory() -> String { - env::current_dir().unwrap().into_os_string().into_string().unwrap() -} - -pub fn repeat_str(s: &str, n: u32) -> String { - let mut repeated = String::new(); - for _ in 0 .. n { - repeated.push_str(s); - } - repeated -} diff --git a/test/cp.rs b/test/cp.rs deleted file mode 100644 index d82c9af49..000000000 --- a/test/cp.rs +++ /dev/null @@ -1,35 +0,0 @@ -use std::fs::File; -use std::io::Read; -use std::path::Path; -use std::process::Command; -use util::*; - -static PROGNAME: &'static str = "./cp"; -static TEST_HELLO_WORLD_SOURCE: &'static str = "hello_world.txt"; -static TEST_HELLO_WORLD_DEST: &'static str = "copy_of_hello_world.txt"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn test_cp_cp() { - // Invoke our binary to make the copy. - let prog = Command::new(PROGNAME) - .arg(TEST_HELLO_WORLD_SOURCE) - .arg(TEST_HELLO_WORLD_DEST) - .status(); - - // Check that the exit code represents a successful copy. - let exit_success = prog.unwrap().success(); - assert_eq!(exit_success, true); - - // Check the content of the destination file that was copied. - let mut contents = String::new(); - let mut f = File::open(Path::new(TEST_HELLO_WORLD_DEST)).unwrap(); - let _ = f.read_to_string(&mut contents); - assert_eq!(contents, "Hello, World!\n"); - - cleanup(TEST_HELLO_WORLD_SOURCE); - cleanup(TEST_HELLO_WORLD_DEST); -} diff --git a/test/cut.rs b/test/cut.rs deleted file mode 100644 index baf32b9f0..000000000 --- a/test/cut.rs +++ /dev/null @@ -1,58 +0,0 @@ -use std::process::Command; -use util::*; - -static PROGNAME: &'static str = "./cut"; -static INPUT: &'static str = "lists.txt"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn test_prefix() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.args(&["-c", "-10", INPUT])); - assert_eq!(result.stdout, get_file_contents("lists_prefix.expected")); -} - -#[test] -fn test_char_range() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.args(&["-c", "4-10", INPUT])); - assert_eq!(result.stdout, get_file_contents("lists_char_range.expected")); -} - -#[test] -fn test_column_to_end_of_line() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.args(&["-d", ":", "-f", "5-", INPUT])); - assert_eq!(result.stdout, get_file_contents("lists_column_to_end_of_line.expected")); -} - -#[test] -fn test_specific_field() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.args(&["-d", " ", "-f", "3", INPUT])); - assert_eq!(result.stdout, get_file_contents("lists_specific_field.expected")); -} - -#[test] -fn test_multiple_fields() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.args(&["-d", ":", "-f", "1,3", INPUT])); - assert_eq!(result.stdout, get_file_contents("lists_multiple_fields.expected")); -} - -#[test] -fn test_tail() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.args(&["-d", ":", "--complement", "-f", "1", INPUT])); - assert_eq!(result.stdout, get_file_contents("lists_tail.expected")); -} - -#[test] -fn test_change_delimiter() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.args(&["-d", ":", "--complement", "--output-delimiter=#", "-f", "1", INPUT])); - assert_eq!(result.stdout, get_file_contents("lists_change_delimiter.expected")); -} diff --git a/test/dirname.rs b/test/dirname.rs deleted file mode 100644 index f0309ce9e..000000000 --- a/test/dirname.rs +++ /dev/null @@ -1,28 +0,0 @@ -use std::process::Command; -use std::str; - -static PROGNAME: &'static str = "./dirname"; - -#[test] -fn test_path_with_trailing_slashes() { - let dir = "/root/alpha/beta/gamma/delta/epsilon/omega//"; - let po = Command::new(PROGNAME) - .arg(dir) - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right(); - assert_eq!(out, "/root/alpha/beta/gamma/delta/epsilon"); -} - -#[test] -fn test_path_without_trailing_slashes() { - let dir = "/root/alpha/beta/gamma/delta/epsilon/omega"; - let po = Command::new(PROGNAME) - .arg(dir) - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right(); - assert_eq!(out, "/root/alpha/beta/gamma/delta/epsilon"); -} diff --git a/test/echo.rs b/test/echo.rs deleted file mode 100644 index b107fd4c4..000000000 --- a/test/echo.rs +++ /dev/null @@ -1,50 +0,0 @@ -use std::process::Command; -use std::str; - -static PROGNAME: &'static str = "./echo"; - -#[test] -fn test_default() { - let po = Command::new(PROGNAME) - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap(); - assert_eq!(out, "\n"); -} - -#[test] -fn test_no_trailing_newline() { - let po = Command::new(PROGNAME) - .arg("-n") - .arg("hello_world") - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap(); - assert_eq!(out, "hello_world"); -} - -#[test] -fn test_enable_escapes() { - let po = Command::new(PROGNAME) - .arg("-e") - .arg("\\\\\\t\\r") - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap(); - assert_eq!(out, "\\\t\r\n"); -} - -#[test] -fn test_disable_escapes() { - let po = Command::new(PROGNAME) - .arg("-E") - .arg("\\b\\c\\e") - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap(); - assert_eq!(out, "\\b\\c\\e\n"); -} diff --git a/test/env.rs b/test/env.rs deleted file mode 100644 index aa2825f29..000000000 --- a/test/env.rs +++ /dev/null @@ -1,74 +0,0 @@ -use std::process::Command; -use std::str; - -static PROGNAME: &'static str = "./env"; - -#[test] -fn test_single_name_value_pair() { - let po = Command::new(PROGNAME) - .arg("FOO=bar") - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap(); - assert!(out.lines().any(|line| line == "FOO=bar")); -} - -#[test] -fn test_multiple_name_value_pairs() { - let po = Command::new(PROGNAME) - .arg("FOO=bar") - .arg("ABC=xyz") - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap(); - assert_eq!(out.lines().filter(|&line| line == "FOO=bar" || line == "ABC=xyz").count(), 2); -} - -#[test] -fn test_ignore_environment() { - let po = Command::new(PROGNAME) - .arg("-i") - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap(); - assert_eq!(out, ""); - - let po = Command::new(PROGNAME) - .arg("-") - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap(); - assert_eq!(out, ""); -} - -#[test] -fn test_null_delimiter() { - let po = Command::new(PROGNAME) - .arg("-i") - .arg("--null") - .arg("FOO=bar") - .arg("ABC=xyz") - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap(); - assert_eq!(out, "FOO=bar\0ABC=xyz\0"); -} - -#[test] -fn test_unset_variable() { - // This test depends on the HOME variable being pre-defined by the - // default shell - let po = Command::new(PROGNAME) - .arg("-u") - .arg("HOME") - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap(); - assert_eq!(out.lines().any(|line| line.starts_with("HOME=")), false); -} diff --git a/test/factor.rs b/test/factor.rs deleted file mode 100644 index 6eadf3469..000000000 --- a/test/factor.rs +++ /dev/null @@ -1,534 +0,0 @@ -/* -* This file is part of the uutils coreutils package. -* -* (c) kwantam -* -* For the full copyright and license information, please view the LICENSE file -* that was distributed with this source code. -*/ - -extern crate libc; -extern crate rand; - -use rand::{weak_rng, Rng}; -use rand::distributions::{IndependentSample, Range}; -use sieve::Sieve; -use std::io::Write; -use std::process::{Command, Stdio}; - -#[path="../src/factor/sieve.rs"] -mod sieve; - -const NUM_PRIMES: usize = 10000; -const LOG_PRIMES: f64 = 14.0; // ceil(log2(NUM_PRIMES)) - -const NUM_TESTS: usize = 100; -const PROGNAME: &'static str = "./factor"; - -#[test] -fn test_random() { - let primes = Sieve::primes().take(NUM_PRIMES).collect::>(); - - let mut rng = weak_rng(); - let mut rand_gt = move |min: u64| { - let mut product = 1u64; - let mut factors = Vec::new(); - while product < min { - // log distribution---higher probability for lower numbers - let factor; - loop { - let next = rng.gen_range(0f64, LOG_PRIMES).exp2().floor() as usize; - if next < NUM_PRIMES { - factor = primes[next]; - break; - } - } - let factor = factor; - - match product.checked_mul(factor) { - Some(p) => { - product = p; - factors.push(factor); - }, - None => break, - }; - } - - factors.sort(); - (product, factors) - }; - - // build an input and expected output string from factor - let mut instring = String::new(); - let mut outstring = String::new(); - for _ in 0..NUM_TESTS { - let (product, factors) = rand_gt(1 << 63); - instring.push_str(&(format!("{} ", product))[..]); - - outstring.push_str(&(format!("{}:", product))[..]); - for factor in factors { - outstring.push_str(&(format!(" {}", factor))[..]); - } - outstring.push_str("\n"); - } - - run(instring.as_bytes(), outstring.as_bytes()); -} - -#[test] -fn test_random_big() { - let mut rng = weak_rng(); - let bitrange_1 = Range::new(14usize, 51); - let mut rand_64 = move || { - // first, choose a random number of bits for the first factor - let f_bit_1 = bitrange_1.ind_sample(&mut rng); - // how many more bits do we need? - let rem = 64 - f_bit_1; - - // we will have a number of additional factors equal to nfacts + 1 - // where nfacts is in [0, floor(rem/14) ) NOTE half-open interval - // Each prime factor is at least 14 bits, hence floor(rem/14) - let nfacts = Range::new(0usize, rem / 14).ind_sample(&mut rng); - // we have to distribute extrabits among the (nfacts + 1) values - let extrabits = rem - (nfacts + 1) * 14; - // (remember, a Range is a half-open interval) - let extrarange = Range::new(0usize, extrabits + 1); - - // to generate an even split of this range, generate n-1 random elements - // in the range, add the desired total value to the end, sort this list, - // and then compute the sequential differences. - let mut f_bits = Vec::new(); - for _ in 0..nfacts { - f_bits.push(extrarange.ind_sample(&mut rng)); - } - f_bits.push(extrabits); - f_bits.sort(); - - // compute sequential differences here. We leave off the +14 bits - // so we can just index PRIMES_BY_BITS - let mut f_bits = f_bits.iter().scan(0, |st,&x| { - let ret = x - *st; // + 14 would give actual number of bits - *st = x; - Some(ret) - }).collect::>(); - // finally, add f_bit_1 in there - f_bits.push(f_bit_1 - 14); // index of f_bit_1 in PRIMES_BY_BITS - let f_bits = f_bits; - - let mut nbits = 0; - let mut product = 1u64; - let mut factors = Vec::new(); - for bit in f_bits { - assert!(bit < 37); - nbits += 14 + bit; - let elm = Range::new(0, PRIMES_BY_BITS[bit].len()).ind_sample(&mut rng); - let factor = PRIMES_BY_BITS[bit][elm]; - factors.push(factor); - product *= factor; - } - assert_eq!(nbits, 64); - - factors.sort(); - (product, factors) - }; - - let mut instring = String::new(); - let mut outstring = String::new(); - for _ in 0..NUM_TESTS { - let (product, factors) = rand_64(); - instring.push_str(&(format!("{} ", product))[..]); - - outstring.push_str(&(format!("{}:", product))[..]); - for factor in factors { - outstring.push_str(&(format!(" {}", factor))[..]); - } - outstring.push_str("\n"); - } - - run(instring.as_bytes(), outstring.as_bytes()); -} - -#[test] -fn test_big_primes() { - let mut instring = String::new(); - let mut outstring = String::new(); - for prime in PRIMES64 { - instring.push_str(&(format!("{} ", prime))[..]); - outstring.push_str(&(format!("{0}: {0}\n", prime))[..]); - } - - run(instring.as_bytes(), outstring.as_bytes()); -} - -fn run(instring: &[u8], outstring: &[u8]) { - // now run factor - let mut process = Command::new(PROGNAME) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - .unwrap_or_else(|e| panic!("{}", e)); - - process.stdin.take().unwrap_or_else(|| panic!("Could not take child process stdin")) - .write_all(instring).unwrap_or_else(|e| panic!("{}", e)); - - let output = process.wait_with_output().unwrap_or_else(|e| panic!("{}", e)); - assert_eq!(&output.stdout[..], outstring); -} - -const PRIMES_BY_BITS: &'static [&'static [u64]] = &[PRIMES14, PRIMES15, PRIMES16, PRIMES17, - PRIMES18, PRIMES19, PRIMES20, PRIMES21, PRIMES22, PRIMES23, PRIMES24, PRIMES25, PRIMES26, - PRIMES27, PRIMES28, PRIMES29, PRIMES30, PRIMES31, PRIMES32, PRIMES33, PRIMES34, PRIMES35, - PRIMES36, PRIMES37, PRIMES38, PRIMES39, PRIMES40, PRIMES41, PRIMES42, PRIMES43, PRIMES44, - PRIMES45, PRIMES46, PRIMES47, PRIMES48, PRIMES49, PRIMES50, -]; - -const PRIMES64: &'static [u64] = &[18446744073709551557, 18446744073709551533, - 18446744073709551521, 18446744073709551437, 18446744073709551427, 18446744073709551359, - 18446744073709551337, 18446744073709551293, 18446744073709551263, 18446744073709551253, - 18446744073709551191, 18446744073709551163, 18446744073709551113, 18446744073709550873, - 18446744073709550791, 18446744073709550773, 18446744073709550771, 18446744073709550719, - 18446744073709550717, 18446744073709550681, 18446744073709550671, 18446744073709550593, - 18446744073709550591, 18446744073709550539, 18446744073709550537, 18446744073709550381, - 18446744073709550341, 18446744073709550293, 18446744073709550237, 18446744073709550147, - 18446744073709550141, 18446744073709550129, 18446744073709550111, 18446744073709550099, - 18446744073709550047, 18446744073709550033, 18446744073709550009, 18446744073709549951, - 18446744073709549861, 18446744073709549817, 18446744073709549811, 18446744073709549777, - 18446744073709549757, 18446744073709549733, 18446744073709549667, 18446744073709549621, - 18446744073709549613, 18446744073709549583, 18446744073709549571, -]; - -const PRIMES14: &'static [u64] = &[16381, 16369, 16363, 16361, 16349, 16339, 16333, 16319, - 16301, 16273, 16267, 16253, 16249, 16231, 16229, 16223, 16217, 16193, 16189, 16187, 16183, - 16141, 16139, 16127, 16111, 16103, 16097, 16091, 16087, 16073, 16069, 16067, 16063, 16061, - 16057, 16033, 16007, 16001, 15991, 15973, 15971, 15959, 15937, 15923, 15919, 15913, 15907, - 15901, 15889, 15887, 15881, 15877, 15859, 15823, 15817, 15809, 15803, 15797, 15791, 15787, - 15773, 15767, 15761, 15749, 15739, 15737, 15733, 15731, 15727, 15683, 15679, 15671, 15667, - 15661, 15649, 15647, 15643, 15641, 15629, 15619, 15607, 15601, 15583, 15581, 15569, 15559, - 15551, 15541, 15527, 15511, 15497, 15493, 15473, 15467, 15461, 15451, 15443, 15439, 15427, - 15413, 15401, 15391, 15383, 15377, 15373, -]; - -const PRIMES15: &'static [u64] = &[32749, 32719, 32717, 32713, 32707, 32693, 32687, 32653, - 32647, 32633, 32621, 32611, 32609, 32603, 32587, 32579, 32573, 32569, 32563, 32561, 32537, - 32533, 32531, 32507, 32503, 32497, 32491, 32479, 32467, 32443, 32441, 32429, 32423, 32413, - 32411, 32401, 32381, 32377, 32371, 32369, 32363, 32359, 32353, 32341, 32327, 32323, 32321, - 32309, 32303, 32299, 32297, 32261, 32257, 32251, 32237, 32233, 32213, 32203, 32191, 32189, - 32183, 32173, 32159, 32143, 32141, 32119, 32117, 32099, 32089, 32083, 32077, 32069, 32063, - 32059, 32057, 32051, 32029, 32027, 32009, 32003, 31991, 31981, 31973, 31963, 31957, 31907, - 31891, 31883, 31873, 31859, 31849, 31847, 31817, 31799, 31793, 31771, 31769, 31751, -]; - -const PRIMES16: &'static [u64] = &[65521, 65519, 65497, 65479, 65449, 65447, 65437, 65423, - 65419, 65413, 65407, 65393, 65381, 65371, 65357, 65353, 65327, 65323, 65309, 65293, 65287, - 65269, 65267, 65257, 65239, 65213, 65203, 65183, 65179, 65173, 65171, 65167, 65147, 65141, - 65129, 65123, 65119, 65111, 65101, 65099, 65089, 65071, 65063, 65053, 65033, 65029, 65027, - 65011, 65003, 64997, 64969, 64951, 64937, 64927, 64921, 64919, 64901, 64891, 64879, 64877, - 64871, 64853, 64849, 64817, 64811, 64793, 64783, 64781, 64763, 64747, 64717, 64709, 64693, - 64679, 64667, 64663, 64661, 64633, 64627, 64621, 64613, 64609, 64601, 64591, 64579, 64577, - 64567, 64553, -]; - -const PRIMES17: &'static [u64] = &[131071, 131063, 131059, 131041, 131023, 131011, 131009, - 130987, 130981, 130973, 130969, 130957, 130927, 130873, 130859, 130843, 130841, 130829, - 130817, 130811, 130807, 130787, 130783, 130769, 130729, 130699, 130693, 130687, 130681, - 130657, 130651, 130649, 130643, 130639, 130633, 130631, 130621, 130619, 130589, 130579, - 130553, 130547, 130531, 130523, 130517, 130513, 130489, 130483, 130477, 130469, 130457, - 130447, 130439, 130423, 130411, 130409, 130399, 130379, 130369, 130367, 130363, 130349, - 130343, 130337, 130307, 130303, 130279, 130267, 130261, 130259, 130253, 130241, 130223, - 130211, 130201, 130199, 130183, 130171, 130147, 130127, 130121, 130099, 130087, 130079, - 130073, 130069, 130057, 130051, -]; - -const PRIMES18: &'static [u64] = &[262139, 262133, 262127, 262121, 262111, 262109, 262103, - 262079, 262069, 262051, 262049, 262027, 262007, 261983, 261977, 261973, 261971, 261959, - 261917, 261887, 261881, 261847, 261823, 261799, 261791, 261787, 261773, 261761, 261757, - 261739, 261721, 261713, 261707, 261697, 261673, 261643, 261641, 261637, 261631, 261619, - 261601, 261593, 261587, 261581, 261577, 261563, 261557, 261529, 261523, 261509, 261467, - 261463, 261451, 261439, 261433, 261431, 261427, 261407, 261389, 261379, 261353, 261347, - 261337, 261329, 261323, 261301, 261281, 261271, 261251, 261241, 261229, 261223, 261169, - 261167, 261127, -]; - -const PRIMES19: &'static [u64] = &[524287, 524269, 524261, 524257, 524243, 524231, 524221, - 524219, 524203, 524201, 524197, 524189, 524171, 524149, 524123, 524119, 524113, 524099, - 524087, 524081, 524071, 524063, 524057, 524053, 524047, 523997, 523987, 523969, 523949, - 523937, 523927, 523907, 523903, 523877, 523867, 523847, 523829, 523801, 523793, 523777, - 523771, 523763, 523759, 523741, 523729, 523717, 523681, 523673, 523669, 523667, 523657, - 523639, 523637, 523631, 523603, 523597, 523577, 523573, 523571, 523553, 523543, 523541, - 523519, 523511, 523493, 523489, 523487, 523463, 523459, 523433, 523427, 523417, 523403, - 523387, 523357, 523351, 523349, 523333, 523307, 523297, -]; - -const PRIMES20: &'static [u64] = &[1048573, 1048571, 1048559, 1048549, 1048517, 1048507, - 1048447, 1048433, 1048423, 1048391, 1048387, 1048367, 1048361, 1048357, 1048343, 1048309, - 1048291, 1048273, 1048261, 1048219, 1048217, 1048213, 1048193, 1048189, 1048139, 1048129, - 1048127, 1048123, 1048063, 1048051, 1048049, 1048043, 1048027, 1048013, 1048009, 1048007, - 1047997, 1047989, 1047979, 1047971, 1047961, 1047941, 1047929, 1047923, 1047887, 1047883, - 1047881, 1047859, 1047841, 1047833, 1047821, 1047779, 1047773, 1047763, 1047751, 1047737, - 1047721, 1047713, 1047703, 1047701, 1047691, 1047689, 1047671, 1047667, 1047653, 1047649, - 1047647, 1047589, 1047587, 1047559, -]; - -const PRIMES21: &'static [u64] = &[2097143, 2097133, 2097131, 2097097, 2097091, 2097083, - 2097047, 2097041, 2097031, 2097023, 2097013, 2096993, 2096987, 2096971, 2096959, 2096957, - 2096947, 2096923, 2096911, 2096909, 2096893, 2096881, 2096873, 2096867, 2096851, 2096837, - 2096807, 2096791, 2096789, 2096777, 2096761, 2096741, 2096737, 2096713, 2096693, 2096687, - 2096681, 2096639, 2096629, 2096621, 2096599, 2096597, 2096569, 2096539, 2096533, 2096483, - 2096449, 2096431, 2096429, 2096411, 2096407, 2096401, 2096399, 2096377, 2096357, 2096291, - 2096273, 2096261, 2096233, 2096231, 2096221, 2096209, 2096191, 2096183, 2096147, -]; - -const PRIMES22: &'static [u64] = &[4194301, 4194287, 4194277, 4194271, 4194247, 4194217, - 4194199, 4194191, 4194187, 4194181, 4194173, 4194167, 4194143, 4194137, 4194131, 4194107, - 4194103, 4194023, 4194011, 4194007, 4193977, 4193971, 4193963, 4193957, 4193939, 4193929, - 4193909, 4193869, 4193807, 4193803, 4193801, 4193789, 4193759, 4193753, 4193743, 4193701, - 4193663, 4193633, 4193573, 4193569, 4193551, 4193549, 4193531, 4193513, 4193507, 4193459, - 4193447, 4193443, 4193417, 4193411, 4193393, 4193389, 4193381, 4193377, 4193369, 4193359, - 4193353, 4193327, 4193309, 4193303, 4193297, -]; - -const PRIMES23: &'static [u64] = &[8388593, 8388587, 8388581, 8388571, 8388547, 8388539, - 8388473, 8388461, 8388451, 8388449, 8388439, 8388427, 8388421, 8388409, 8388377, 8388371, - 8388319, 8388301, 8388287, 8388283, 8388277, 8388239, 8388209, 8388187, 8388113, 8388109, - 8388091, 8388071, 8388059, 8388019, 8388013, 8387999, 8387993, 8387959, 8387957, 8387947, - 8387933, 8387921, 8387917, 8387891, 8387879, 8387867, 8387861, 8387857, 8387839, 8387831, - 8387809, 8387807, 8387741, 8387737, 8387723, 8387707, 8387671, 8387611, 8387609, 8387591, -]; - -const PRIMES24: &'static [u64] = &[16777213, 16777199, 16777183, 16777153, 16777141, 16777139, - 16777127, 16777121, 16777099, 16777049, 16777027, 16776989, 16776973, 16776971, 16776967, - 16776961, 16776941, 16776937, 16776931, 16776919, 16776901, 16776899, 16776869, 16776857, - 16776839, 16776833, 16776817, 16776763, 16776731, 16776719, 16776713, 16776691, 16776689, - 16776679, 16776659, 16776631, 16776623, 16776619, 16776607, 16776593, 16776581, 16776547, - 16776521, 16776491, 16776481, 16776469, 16776451, 16776401, 16776391, 16776379, 16776371, - 16776367, 16776343, 16776337, 16776317, 16776313, 16776289, 16776217, 16776211, -]; - -const PRIMES25: &'static [u64] = &[33554393, 33554383, 33554371, 33554347, 33554341, 33554317, - 33554291, 33554273, 33554267, 33554249, 33554239, 33554221, 33554201, 33554167, 33554159, - 33554137, 33554123, 33554093, 33554083, 33554077, 33554051, 33554021, 33554011, 33554009, - 33553999, 33553991, 33553969, 33553967, 33553909, 33553901, 33553879, 33553837, 33553799, - 33553787, 33553771, 33553769, 33553759, 33553747, 33553739, 33553727, 33553697, 33553693, - 33553679, 33553661, 33553657, 33553651, 33553649, 33553633, 33553613, 33553607, 33553577, - 33553549, 33553547, 33553537, 33553519, 33553517, 33553511, 33553489, 33553463, 33553451, - 33553417, -]; - -const PRIMES26: &'static [u64] = &[67108859, 67108837, 67108819, 67108777, 67108763, - 67108757, 67108753, 67108747, 67108739, 67108729, 67108721, 67108709, 67108693, 67108669, - 67108667, 67108661, 67108649, 67108633, 67108597, 67108579, 67108529, 67108511, 67108507, - 67108493, 67108471, 67108463, 67108453, 67108439, 67108387, 67108373, 67108369, 67108351, - 67108331, 67108313, 67108303, 67108289, 67108271, 67108219, 67108207, 67108201, 67108199, - 67108187, 67108183, 67108177, 67108127, 67108109, 67108081, 67108049, 67108039, 67108037, - 67108033, 67108009, 67108007, 67108003, 67107983, 67107977, 67107967, 67107941, 67107919, - 67107913, 67107883, 67107881, 67107871, 67107863, -]; - -const PRIMES27: &'static [u64] = &[134217689, 134217649, 134217617, 134217613, 134217593, - 134217541, 134217529, 134217509, 134217497, 134217493, 134217487, 134217467, 134217439, - 134217437, 134217409, 134217403, 134217401, 134217367, 134217361, 134217353, 134217323, - 134217301, 134217277, 134217257, 134217247, 134217221, 134217199, 134217173, 134217163, - 134217157, 134217131, 134217103, 134217089, 134217079, 134217049, 134217047, 134217043, - 134217001, 134216987, 134216947, 134216939, 134216933, 134216911, 134216899, 134216881, - 134216869, 134216867, 134216861, 134216837, 134216827, 134216807, 134216801, 134216791, - 134216783, 134216777, 134216759, 134216737, 134216729, -]; - -const PRIMES28: &'static [u64] = &[268435399, 268435367, 268435361, 268435337, 268435331, - 268435313, 268435291, 268435273, 268435243, 268435183, 268435171, 268435157, 268435147, - 268435133, 268435129, 268435121, 268435109, 268435091, 268435067, 268435043, 268435039, - 268435033, 268435019, 268435009, 268435007, 268434997, 268434979, 268434977, 268434961, - 268434949, 268434941, 268434937, 268434857, 268434841, 268434827, 268434821, 268434787, - 268434781, 268434779, 268434773, 268434731, 268434721, 268434713, 268434707, 268434703, - 268434697, 268434659, 268434623, 268434619, 268434581, 268434577, 268434563, 268434557, - 268434547, 268434511, 268434499, 268434479, 268434461, -]; - -const PRIMES29: &'static [u64] = &[536870909, 536870879, 536870869, 536870849, 536870839, - 536870837, 536870819, 536870813, 536870791, 536870779, 536870767, 536870743, 536870729, - 536870723, 536870717, 536870701, 536870683, 536870657, 536870641, 536870627, 536870611, - 536870603, 536870599, 536870573, 536870569, 536870563, 536870561, 536870513, 536870501, - 536870497, 536870473, 536870401, 536870363, 536870317, 536870303, 536870297, 536870273, - 536870267, 536870239, 536870233, 536870219, 536870171, 536870167, 536870153, 536870123, - 536870063, 536870057, 536870041, 536870027, 536869999, 536869951, 536869943, 536869937, - 536869919, 536869901, 536869891, -]; - -const PRIMES30: &'static [u64] = &[1073741789, 1073741783, 1073741741, 1073741723, 1073741719, - 1073741717, 1073741689, 1073741671, 1073741663, 1073741651, 1073741621, 1073741567, 1073741561, - 1073741527, 1073741503, 1073741477, 1073741467, 1073741441, 1073741419, 1073741399, 1073741387, - 1073741381, 1073741371, 1073741329, 1073741311, 1073741309, 1073741287, 1073741237, 1073741213, - 1073741197, 1073741189, 1073741173, 1073741101, 1073741077, 1073741047, 1073740963, 1073740951, - 1073740933, 1073740909, 1073740879, 1073740853, 1073740847, 1073740819, 1073740807, -]; - -const PRIMES31: &'static [u64] = &[2147483647, 2147483629, 2147483587, 2147483579, 2147483563, - 2147483549, 2147483543, 2147483497, 2147483489, 2147483477, 2147483423, 2147483399, 2147483353, - 2147483323, 2147483269, 2147483249, 2147483237, 2147483179, 2147483171, 2147483137, 2147483123, - 2147483077, 2147483069, 2147483059, 2147483053, 2147483033, 2147483029, 2147482951, 2147482949, - 2147482943, 2147482937, 2147482921, 2147482877, 2147482873, 2147482867, 2147482859, 2147482819, - 2147482817, 2147482811, 2147482801, 2147482763, 2147482739, 2147482697, 2147482693, 2147482681, - 2147482663, 2147482661, -]; - -const PRIMES32: &'static [u64] = &[4294967291, 4294967279, 4294967231, 4294967197, 4294967189, - 4294967161, 4294967143, 4294967111, 4294967087, 4294967029, 4294966997, 4294966981, 4294966943, - 4294966927, 4294966909, 4294966877, 4294966829, 4294966813, 4294966769, 4294966667, 4294966661, - 4294966657, 4294966651, 4294966639, 4294966619, 4294966591, 4294966583, 4294966553, 4294966477, - 4294966447, 4294966441, 4294966427, 4294966373, 4294966367, 4294966337, 4294966297, -]; - -const PRIMES33: &'static [u64] = &[8589934583, 8589934567, 8589934543, 8589934513, 8589934487, - 8589934307, 8589934291, 8589934289, 8589934271, 8589934237, 8589934211, 8589934207, 8589934201, - 8589934187, 8589934151, 8589934141, 8589934139, 8589934117, 8589934103, 8589934099, 8589934091, - 8589934069, 8589934049, 8589934027, 8589934007, 8589933973, 8589933971, 8589933967, 8589933931, - 8589933917, 8589933907, 8589933853, 8589933827, 8589933823, 8589933787, 8589933773, 8589933733, - 8589933731, 8589933721, 8589933683, 8589933647, 8589933641, 8589933637, 8589933631, 8589933629, - 8589933619, 8589933601, 8589933581, -]; - -const PRIMES34: &'static [u64] = &[17179869143, 17179869107, 17179869071, 17179869053, - 17179869041, 17179869019, 17179868999, 17179868977, 17179868957, 17179868903, 17179868899, - 17179868887, 17179868879, 17179868873, 17179868869, 17179868861, 17179868843, 17179868833, - 17179868809, 17179868807, 17179868777, 17179868759, 17179868729, 17179868711, 17179868683, - 17179868681, 17179868597, 17179868549, 17179868543, 17179868521, 17179868513, 17179868479, - 17179868443, 17179868437, 17179868429, 17179868383, 17179868369, 17179868357, 17179868353, - 17179868351, 17179868333, 17179868317, 17179868309, 17179868297, 17179868287, 17179868249, - 17179868243, 17179868183, -]; - -const PRIMES35: &'static [u64] = &[34359738337, 34359738319, 34359738307, 34359738299, - 34359738289, 34359738247, 34359738227, 34359738121, 34359738059, 34359738043, 34359738011, - 34359737917, 34359737869, 34359737849, 34359737837, 34359737821, 34359737813, 34359737791, - 34359737777, 34359737771, 34359737717, 34359737591, 34359737567, 34359737549, 34359737519, - 34359737497, 34359737479, 34359737407, 34359737393, 34359737371, -]; - -const PRIMES36: &'static [u64] = &[68719476731, 68719476719, 68719476713, 68719476671, - 68719476619, 68719476599, 68719476577, 68719476563, 68719476547, 68719476503, 68719476493, - 68719476479, 68719476433, 68719476407, 68719476391, 68719476389, 68719476377, 68719476361, - 68719476323, 68719476307, 68719476281, 68719476271, 68719476257, 68719476247, 68719476209, - 68719476197, 68719476181, 68719476169, 68719476157, 68719476149, 68719476109, 68719476053, - 68719476047, 68719476019, 68719475977, 68719475947, 68719475933, 68719475911, 68719475893, - 68719475879, 68719475837, 68719475827, 68719475809, 68719475791, 68719475779, 68719475771, - 68719475767, 68719475731, 68719475729, -]; - -const PRIMES37: &'static [u64] = &[137438953447, 137438953441, 137438953427, 137438953403, - 137438953349, 137438953331, 137438953273, 137438953271, 137438953121, 137438953097, - 137438953037, 137438953009, 137438952953, 137438952901, 137438952887, 137438952869, - 137438952853, 137438952731, 137438952683, 137438952611, 137438952529, 137438952503, - 137438952491, -]; - -const PRIMES38: &'static [u64] = &[274877906899, 274877906857, 274877906837, 274877906813, - 274877906791, 274877906759, 274877906753, 274877906717, 274877906713, 274877906687, - 274877906647, 274877906629, 274877906627, 274877906573, 274877906543, 274877906491, - 274877906477, 274877906473, 274877906431, 274877906419, 274877906341, 274877906333, - 274877906327, 274877906321, 274877906309, 274877906267, 274877906243, 274877906213, - 274877906209, 274877906203, 274877906179, 274877906167, 274877906119, 274877906063, - 274877906053, 274877906021, 274877905931, -]; - -const PRIMES39: &'static [u64] = &[549755813881, 549755813869, 549755813821, 549755813797, - 549755813753, 549755813723, 549755813669, 549755813657, 549755813647, 549755813587, - 549755813561, 549755813513, 549755813507, 549755813461, 549755813417, 549755813401, - 549755813371, 549755813359, 549755813357, 549755813351, 549755813339, 549755813317, - 549755813311, 549755813281, 549755813239, 549755813231, 549755813213, 549755813207, - 549755813197, 549755813183, 549755813161, 549755813149, 549755813147, 549755813143, - 549755813141, 549755813059, 549755813027, 549755813003, 549755812951, 549755812937, - 549755812933, 549755812889, 549755812867, -]; - -const PRIMES40: &'static [u64] = &[1099511627689, 1099511627609, 1099511627581, 1099511627573, - 1099511627563, 1099511627491, 1099511627483, 1099511627477, 1099511627387, 1099511627339, - 1099511627321, 1099511627309, 1099511627297, 1099511627293, 1099511627261, 1099511627213, - 1099511627191, 1099511627177, 1099511627173, 1099511627143, 1099511627089, 1099511626987, - 1099511626949, 1099511626937, 1099511626793, 1099511626781, 1099511626771, -]; - -const PRIMES41: &'static [u64] = &[2199023255531, 2199023255521, 2199023255497, 2199023255489, - 2199023255479, 2199023255477, 2199023255461, 2199023255441, 2199023255419, 2199023255413, - 2199023255357, 2199023255327, 2199023255291, 2199023255279, 2199023255267, 2199023255243, - 2199023255203, 2199023255171, 2199023255137, 2199023255101, 2199023255087, 2199023255081, - 2199023255069, 2199023255027, 2199023255021, 2199023254979, 2199023254933, 2199023254913, - 2199023254907, 2199023254903, 2199023254843, 2199023254787, 2199023254699, 2199023254693, - 2199023254657, 2199023254567, -]; - -const PRIMES42: &'static [u64] = &[4398046511093, 4398046511087, 4398046511071, 4398046511051, - 4398046511039, 4398046510961, 4398046510943, 4398046510939, 4398046510889, 4398046510877, - 4398046510829, 4398046510787, 4398046510771, 4398046510751, 4398046510733, 4398046510721, - 4398046510643, 4398046510639, 4398046510597, 4398046510577, 4398046510547, 4398046510531, - 4398046510463, 4398046510397, 4398046510391, 4398046510379, 4398046510357, 4398046510331, - 4398046510327, 4398046510313, 4398046510283, 4398046510279, 4398046510217, 4398046510141, - 4398046510133, 4398046510103, 4398046510093, -]; - -const PRIMES43: &'static [u64] = &[8796093022151, 8796093022141, 8796093022091, 8796093022033, - 8796093021953, 8796093021941, 8796093021917, 8796093021899, 8796093021889, 8796093021839, - 8796093021803, 8796093021791, 8796093021769, 8796093021763, 8796093021743, 8796093021671, - 8796093021607, 8796093021587, 8796093021533, 8796093021523, 8796093021517, 8796093021493, - 8796093021467, 8796093021461, 8796093021449, 8796093021409, 8796093021407, 8796093021371, - 8796093021347, 8796093021337, 8796093021281, 8796093021269, -]; - -const PRIMES44: &'static [u64] = &[17592186044399, 17592186044299, 17592186044297, 17592186044287, - 17592186044273, 17592186044267, 17592186044129, 17592186044089, 17592186044057, 17592186044039, - 17592186043987, 17592186043921, 17592186043889, 17592186043877, 17592186043841, 17592186043829, - 17592186043819, 17592186043813, 17592186043807, 17592186043741, 17592186043693, 17592186043667, - 17592186043631, 17592186043591, 17592186043577, 17592186043547, 17592186043483, 17592186043451, - 17592186043433, 17592186043409, -]; - -const PRIMES45: &'static [u64] = &[35184372088777, 35184372088763, 35184372088751, 35184372088739, - 35184372088711, 35184372088699, 35184372088693, 35184372088673, 35184372088639, 35184372088603, - 35184372088571, 35184372088517, 35184372088493, 35184372088471, 35184372088403, 35184372088391, - 35184372088379, 35184372088363, 35184372088321, 35184372088319, 35184372088279, 35184372088259, - 35184372088249, 35184372088241, 35184372088223, 35184372088183, 35184372088097, 35184372088081, - 35184372088079, 35184372088051, 35184372088043, 35184372088039, 35184372087937, 35184372087929, - 35184372087923, 35184372087881, 35184372087877, 35184372087869, -]; - -const PRIMES46: &'static [u64] = &[70368744177643, 70368744177607, 70368744177601, 70368744177587, - 70368744177497, 70368744177467, 70368744177427, 70368744177377, 70368744177359, 70368744177353, - 70368744177331, 70368744177289, 70368744177283, 70368744177271, 70368744177257, 70368744177227, - 70368744177167, 70368744177113, 70368744177029, 70368744176959, 70368744176921, 70368744176909, - 70368744176879, 70368744176867, 70368744176833, 70368744176827, 70368744176807, 70368744176779, - 70368744176777, 70368744176729, 70368744176719, 70368744176711, -]; - -const PRIMES47: &'static [u64] = &[140737488355213, 140737488355201, 140737488355181, - 140737488355049, 140737488355031, 140737488354989, 140737488354893, 140737488354787, - 140737488354709, 140737488354679, 140737488354613, 140737488354557, 140737488354511, - 140737488354431, 140737488354413, 140737488354409, 140737488354373, 140737488354347, - 140737488354329, -]; - -const PRIMES48: &'static [u64] = &[281474976710597, 281474976710591, 281474976710567, - 281474976710563, 281474976710509, 281474976710491, 281474976710467, 281474976710423, - 281474976710413, 281474976710399, 281474976710339, 281474976710327, 281474976710287, - 281474976710197, 281474976710143, 281474976710131, 281474976710129, 281474976710107, - 281474976710089, 281474976710087, 281474976710029, 281474976709987, 281474976709891, - 281474976709859, 281474976709831, 281474976709757, 281474976709741, 281474976709711, - 281474976709649, 281474976709637, -]; - -const PRIMES49: &'static [u64] = &[562949953421231, 562949953421201, 562949953421189, - 562949953421173, 562949953421131, 562949953421111, 562949953421099, 562949953421047, - 562949953421029, 562949953420973, 562949953420871, 562949953420867, 562949953420837, - 562949953420793, 562949953420747, 562949953420741, 562949953420733, 562949953420727, - 562949953420609, 562949953420571, 562949953420559, 562949953420553, 562949953420523, - 562949953420507, 562949953420457, 562949953420403, 562949953420373, 562949953420369, - 562949953420343, 562949953420303, 562949953420297, -]; - -const PRIMES50: &'static [u64] = &[1125899906842597, 1125899906842589, 1125899906842573, - 1125899906842553, 1125899906842511, 1125899906842507, 1125899906842493, 1125899906842463, - 1125899906842429, 1125899906842391, 1125899906842357, 1125899906842283, 1125899906842273, - 1125899906842247, 1125899906842201, 1125899906842177, 1125899906842079, 1125899906842033, - 1125899906842021, 1125899906842013, 1125899906841973, 1125899906841971, 1125899906841959, - 1125899906841949, 1125899906841943, 1125899906841917, 1125899906841901, 1125899906841883, - 1125899906841859, 1125899906841811, 1125899906841803, 1125899906841751, 1125899906841713, - 1125899906841673, 1125899906841653, 1125899906841623, 1125899906841613, -]; diff --git a/test/false.rs b/test/false.rs deleted file mode 100644 index 2cd6a327d..000000000 --- a/test/false.rs +++ /dev/null @@ -1,9 +0,0 @@ -use std::process::Command; - -static PROGNAME: &'static str = "./false"; - -#[test] -fn test_exit_code() { - let exit_status = Command::new(PROGNAME).status().unwrap().success(); - assert_eq!(exit_status, false); -} diff --git a/test/fold.rs b/test/fold.rs deleted file mode 100644 index ecae80303..000000000 --- a/test/fold.rs +++ /dev/null @@ -1,53 +0,0 @@ -use std::fs::File; -use std::io::Read; -use std::path::Path; -use std::process::Command; - -static PROGNAME: &'static str = "./fold"; - -#[test] -fn test_default_80_column_wrap() { - let po = Command::new(PROGNAME) - .arg("lorem_ipsum.txt") - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - fold_helper(po.stdout, "lorem_ipsum_80_column.expected"); -} - -#[test] -fn test_40_column_hard_cutoff() { - let po = Command::new(PROGNAME) - .arg("-w") - .arg("40") - .arg("lorem_ipsum.txt") - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - fold_helper(po.stdout, "lorem_ipsum_40_column_hard.expected"); -} - -#[test] -fn test_40_column_word_boundary() { - let po = Command::new(PROGNAME) - .arg("-s") - .arg("-w") - .arg("40") - .arg("lorem_ipsum.txt") - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - fold_helper(po.stdout, "lorem_ipsum_40_column_word.expected"); -} - -fn fold_helper(output: Vec, filename: &str) { - let mut f = File::open(Path::new(filename)).unwrap_or_else(|err| { - panic!("{}", err) - }); - let mut expected = vec!(); - match f.read_to_end(&mut expected) { - Ok(_) => {}, - Err(err) => panic!("{}", err) - } - assert_eq!(String::from_utf8(output).unwrap(), String::from_utf8(expected).unwrap()); -} diff --git a/test/head.rs b/test/head.rs deleted file mode 100644 index 4368225b3..000000000 --- a/test/head.rs +++ /dev/null @@ -1,72 +0,0 @@ -use std::process::Command; -use util::*; - -static PROGNAME: &'static str = "./head"; -static INPUT: &'static str = "lorem_ipsum.txt"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn test_stdin_default() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd, get_file_contents(INPUT)); - assert_eq!(result.stdout, get_file_contents("lorem_ipsum_default.expected")); -} - -#[test] -fn test_stdin_1_line_obsolete() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-1"]), get_file_contents(INPUT)); - assert_eq!(result.stdout, get_file_contents("lorem_ipsum_1_line.expected")); -} - -#[test] -fn test_stdin_1_line() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-n", "1"]), get_file_contents(INPUT)); - assert_eq!(result.stdout, get_file_contents("lorem_ipsum_1_line.expected")); -} - -#[test] -fn test_stdin_5_chars() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-c", "5"]), get_file_contents(INPUT)); - assert_eq!(result.stdout, get_file_contents("lorem_ipsum_5_chars.expected")); -} - -#[test] -fn test_single_default() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.arg(INPUT)); - assert_eq!(result.stdout, get_file_contents("lorem_ipsum_default.expected")); -} - -#[test] -fn test_single_1_line_obsolete() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.args(&["-1", INPUT])); - assert_eq!(result.stdout, get_file_contents("lorem_ipsum_1_line.expected")); -} - -#[test] -fn test_single_1_line() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.args(&["-n", "1", INPUT])); - assert_eq!(result.stdout, get_file_contents("lorem_ipsum_1_line.expected")); -} - -#[test] -fn test_single_5_chars() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.args(&["-c", "5", INPUT])); - assert_eq!(result.stdout, get_file_contents("lorem_ipsum_5_chars.expected")); -} - -#[test] -fn test_verbose() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.args(&["-v", INPUT])); - assert_eq!(result.stdout, get_file_contents("lorem_ipsum_verbose.expected")); -} diff --git a/test/link.rs b/test/link.rs deleted file mode 100644 index 44ce2c2bd..000000000 --- a/test/link.rs +++ /dev/null @@ -1,49 +0,0 @@ -extern crate libc; - -use std::process::Command; -use util::*; - -static PROGNAME: &'static str = "./link"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn test_link_existing_file() { - let file = "test_link_existing_file"; - let link = "test_link_existing_file_link"; - - touch(file); - set_file_contents(file, "foobar"); - assert!(file_exists(file)); - - let result = run(Command::new(PROGNAME).args(&[file, link])); - assert_empty_stderr!(result); - assert!(result.success); - assert!(file_exists(file)); - assert!(file_exists(link)); - assert_eq!(get_file_contents(file), get_file_contents(link)); -} - -#[test] -fn test_link_no_circular() { - let link = "test_link_no_circular"; - - let result = run(Command::new(PROGNAME).args(&[link, link])); - assert_eq!(result.stderr, "link: error: No such file or directory (os error 2)\n"); - assert!(!result.success); - assert!(!file_exists(link)); -} - -#[test] -fn test_link_nonexistent_file() { - let file = "test_link_nonexistent_file"; - let link = "test_link_nonexistent_file_link"; - - let result = run(Command::new(PROGNAME).args(&[file, link])); - assert_eq!(result.stderr, "link: error: No such file or directory (os error 2)\n"); - assert!(!result.success); - assert!(!file_exists(file)); - assert!(!file_exists(link)); -} diff --git a/test/ln.rs b/test/ln.rs deleted file mode 100644 index 9020dc0c5..000000000 --- a/test/ln.rs +++ /dev/null @@ -1,354 +0,0 @@ -extern crate libc; - -use std::process::Command; -use util::*; - -static PROGNAME: &'static str = "./ln"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn test_symlink_existing_file() { - let file = "test_symlink_existing_file"; - let link = "test_symlink_existing_file_link"; - - touch(file); - - let result = run(Command::new(PROGNAME).args(&["-s", file, link])); - assert_empty_stderr!(result); - assert!(result.success); - assert!(file_exists(file)); - assert!(is_symlink(link)); - assert_eq!(resolve_link(link), file); -} - -#[test] -fn test_symlink_dangling_file() { - let file = "test_symlink_dangling_file"; - let link = "test_symlink_dangling_file_link"; - - let result = run(Command::new(PROGNAME).args(&["-s", file, link])); - assert_empty_stderr!(result); - assert!(result.success); - assert!(!file_exists(file)); - assert!(is_symlink(link)); - assert_eq!(resolve_link(link), file); -} - -#[test] -fn test_symlink_existing_directory() { - let dir = "test_symlink_existing_dir"; - let link = "test_symlink_existing_dir_link"; - - mkdir(dir); - - let result = run(Command::new(PROGNAME).args(&["-s", dir, link])); - assert_empty_stderr!(result); - assert!(result.success); - assert!(dir_exists(dir)); - assert!(is_symlink(link)); - assert_eq!(resolve_link(link), dir); -} - -#[test] -fn test_symlink_dangling_directory() { - let dir = "test_symlink_dangling_dir"; - let link = "test_symlink_dangling_dir_link"; - - let result = run(Command::new(PROGNAME).args(&["-s", dir, link])); - assert_empty_stderr!(result); - assert!(result.success); - assert!(!dir_exists(dir)); - assert!(is_symlink(link)); - assert_eq!(resolve_link(link), dir); -} - -#[test] -fn test_symlink_circular() { - let link = "test_symlink_circular"; - - let result = run(Command::new(PROGNAME).args(&["-s", link])); - assert_empty_stderr!(result); - assert!(result.success); - assert!(is_symlink(link)); - assert_eq!(resolve_link(link), link); -} - -#[test] -fn test_symlink_dont_overwrite() { - let file = "test_symlink_dont_overwrite"; - let link = "test_symlink_dont_overwrite_link"; - - touch(file); - touch(link); - - let result = run(Command::new(PROGNAME).args(&["-s", file, link])); - assert!(!result.success); - assert!(file_exists(file)); - assert!(file_exists(link)); - assert!(!is_symlink(link)); -} - -#[test] -fn test_symlink_overwrite_force() { - let file_a = "test_symlink_overwrite_force_a"; - let file_b = "test_symlink_overwrite_force_b"; - let link = "test_symlink_overwrite_force_link"; - - // Create symlink - symlink(file_a, link); - assert!(is_symlink(link)); - assert_eq!(resolve_link(link), file_a); - - // Force overwrite of existing symlink - let result = run(Command::new(PROGNAME).args(&["--force", "-s", file_b, link])); - assert!(result.success); - assert!(is_symlink(link)); - assert_eq!(resolve_link(link), file_b); -} - -#[test] -fn test_symlink_interactive() { - let file = "test_symlink_interactive_file"; - let link = "test_symlink_interactive_file_link"; - - touch(file); - touch(link); - - let result1 = run_piped_stdin(Command::new(PROGNAME).args(&["-i", "-s", file, link]), b"n"); - - assert_empty_stderr!(result1); - assert!(result1.success); - - assert!(file_exists(file)); - assert!(!is_symlink(link)); - - let result2 = run_piped_stdin(Command::new(PROGNAME).args(&["-i", "-s", file, link]), b"Yesh"); - - assert_empty_stderr!(result2); - assert!(result2.success); - - assert!(file_exists(file)); - assert!(is_symlink(link)); - assert_eq!(resolve_link(link), file); -} - -#[test] -fn test_symlink_simple_backup() { - let file = "test_symlink_simple_backup"; - let link = "test_symlink_simple_backup_link"; - - touch(file); - symlink(file, link); - assert!(file_exists(file)); - assert!(is_symlink(link)); - assert_eq!(resolve_link(link), file); - - let result = run(Command::new(PROGNAME).args(&["-b", "-s", file, link])); - - assert_empty_stderr!(result); - assert!(result.success); - assert!(file_exists(file)); - - assert!(is_symlink(link)); - assert_eq!(resolve_link(link), file); - - let backup = &format!("{}~", link); - assert!(is_symlink(backup)); - assert_eq!(resolve_link(backup), file); -} - -#[test] -fn test_symlink_custom_backup_suffix() { - let file = "test_symlink_custom_backup_suffix"; - let link = "test_symlink_custom_backup_suffix_link"; - let suffix = "super-suffix-of-the-century"; - - touch(file); - symlink(file, link); - assert!(file_exists(file)); - assert!(is_symlink(link)); - assert_eq!(resolve_link(link), file); - - let arg = &format!("--suffix={}", suffix); - let result = run(Command::new(PROGNAME).args(&["-b", arg, "-s", file, link])); - - assert_empty_stderr!(result); - assert!(result.success); - assert!(file_exists(file)); - - assert!(is_symlink(link)); - assert_eq!(resolve_link(link), file); - - let backup = &format!("{}{}", link, suffix); - assert!(is_symlink(backup)); - assert_eq!(resolve_link(backup), file); -} - -#[test] -fn test_symlink_backup_numbering() { - let file = "test_symlink_backup_numbering"; - let link = "test_symlink_backup_numbering_link"; - - touch(file); - symlink(file, link); - assert!(file_exists(file)); - assert!(is_symlink(link)); - assert_eq!(resolve_link(link), file); - - let result = run(Command::new(PROGNAME).args(&["-s", "--backup=t", file, link])); - - assert_empty_stderr!(result); - assert!(result.success); - assert!(file_exists(file)); - - assert!(is_symlink(link)); - assert_eq!(resolve_link(link), file); - - let backup = &format!("{}.~1~", link); - assert!(is_symlink(backup)); - assert_eq!(resolve_link(backup), file); -} - -#[test] -fn test_symlink_existing_backup() { - let file = "test_symlink_existing_backup"; - let link = "test_symlink_existing_backup_link"; - let link_backup = "test_symlink_existing_backup_link.~1~"; - let resulting_backup = "test_symlink_existing_backup_link.~2~"; - - // Create symlink and verify - touch(file); - symlink(file, link); - assert!(file_exists(file)); - assert!(is_symlink(link)); - assert_eq!(resolve_link(link), file); - - // Create backup symlink and verify - symlink(file, link_backup); - assert!(file_exists(file)); - assert!(is_symlink(link_backup)); - assert_eq!(resolve_link(link_backup), file); - - let result = run(Command::new(PROGNAME).args(&["-s", "--backup=nil", file, link])); - - assert_empty_stderr!(result); - assert!(result.success); - assert!(file_exists(file)); - - assert!(is_symlink(link_backup)); - assert_eq!(resolve_link(link_backup), file); - - assert!(is_symlink(resulting_backup)); - assert_eq!(resolve_link(resulting_backup), file); -} - -#[test] -fn test_symlink_target_dir() { - let dir = "test_ln_target_dir_dir"; - let file_a = "test_ln_target_dir_file_a"; - let file_b = "test_ln_target_dir_file_b"; - - touch(file_a); - touch(file_b); - mkdir(dir); - - let result = run(Command::new(PROGNAME).args(&["-s", "-t", dir, file_a, file_b])); - - assert_empty_stderr!(result); - assert!(result.success); - - let file_a_link = &format!("{}/{}", dir, file_a); - assert!(is_symlink(file_a_link)); - assert_eq!(resolve_link(file_a_link), file_a); - - let file_b_link = &format!("{}/{}", dir, file_b); - assert!(is_symlink(file_b_link)); - assert_eq!(resolve_link(file_b_link), file_b); -} - -#[test] -fn test_symlink_overwrite_dir() { - let path_a = "test_symlink_overwrite_dir_a"; - let path_b = "test_symlink_overwrite_dir_b"; - - touch(path_a); - mkdir(path_b); - - let result = run(Command::new(PROGNAME).args(&["-s", "-T", path_a, path_b])); - - assert_empty_stderr!(result); - assert!(result.success); - - assert!(file_exists(path_a)); - assert!(is_symlink(path_b)); - assert_eq!(resolve_link(path_b), path_a); -} - -#[test] -fn test_symlink_overwrite_nonempty_dir() { - let path_a = "test_symlink_overwrite_nonempty_dir_a"; - let path_b = "test_symlink_overwrite_nonempty_dir_b"; - let dummy = "test_symlink_overwrite_nonempty_dir_b/file"; - - touch(path_a); - mkdir(path_b); - touch(dummy); - - let result = run(Command::new(PROGNAME).args(&["-v", "-T", "-s", path_a, path_b])); - - // Not same error as GNU; the error message is a Rust builtin - // TODO: test (and implement) correct error message (or at least decide whether to do so) - // Current: "ln: error: Directory not empty (os error 66)" - // GNU: "ln: cannot link 'a' to 'b': Directory not empty" - assert!(result.stderr.len() > 0); - - // Verbose output for the link should not be shown on failure - assert!(result.stdout.len() == 0); - - assert!(!result.success); - assert!(file_exists(path_a)); - assert!(dir_exists(path_b)); -} - -#[test] -fn test_symlink_errors() { - let dir = "test_symlink_errors_dir"; - let file_a = "test_symlink_errors_file_a"; - let file_b = "test_symlink_errors_file_b"; - - mkdir(dir); - touch(file_a); - touch(file_b); - - // $ ln -T -t a b - // ln: cannot combine --target-directory (-t) and --no-target-directory (-T) - let result = run(Command::new(PROGNAME).args(&["-T", "-t", dir, file_a, file_b])); - assert_eq!(result.stderr, - "ln: error: cannot combine --target-directory (-t) and --no-target-directory (-T)\n"); - assert!(!result.success); -} - -#[test] -fn test_symlink_verbose() { - let file_a = "test_symlink_verbose_file_a"; - let file_b = "test_symlink_verbose_file_b"; - - touch(file_a); - - let result = run(Command::new(PROGNAME).args(&["-v", file_a, file_b])); - assert_empty_stderr!(result); - assert_eq!(result.stdout, - format!("'{}' -> '{}'\n", file_b, file_a)); - assert!(result.success); - - touch(file_b); - - let result = run(Command::new(PROGNAME).args(&["-v", "-b", file_a, file_b])); - assert_empty_stderr!(result); - assert_eq!(result.stdout, - format!("'{}' -> '{}' (backup: '{}~')\n", file_b, file_a, file_b)); - assert!(result.success); -} diff --git a/test/mkdir.rs b/test/mkdir.rs deleted file mode 100644 index 463688dc1..000000000 --- a/test/mkdir.rs +++ /dev/null @@ -1,58 +0,0 @@ -use std::process::Command; -use util::*; - -static PROGNAME: &'static str = "./mkdir"; -static TEST_DIR1: &'static str = "mkdir_test1"; -static TEST_DIR2: &'static str = "mkdir_test2"; -static TEST_DIR3: &'static str = "mkdir_test3"; -static TEST_DIR4: &'static str = "mkdir_test4/mkdir_test4_1"; -static TEST_DIR5: &'static str = "mkdir_test5/mkdir_test5_1"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn test_mkdir_mkdir() { - let mut cmd = Command::new(PROGNAME); - let exit_success = run(&mut cmd.arg(TEST_DIR1)).success; - cleanup(TEST_DIR1); - assert_eq!(exit_success, true); -} - -#[test] -fn test_mkdir_dup_dir() { - let mut cmd = Command::new(PROGNAME); - let exit_success = run(&mut cmd.arg(TEST_DIR2)).success; - if !exit_success { - cleanup(TEST_DIR2); - panic!(); - } - let exit_success2 = run(&mut cmd.arg(TEST_DIR2)).success; - cleanup(TEST_DIR2); - assert_eq!(exit_success2, false); -} - -#[test] -fn test_mkdir_mode() { - let mut cmd = Command::new(PROGNAME); - let exit_success = run(&mut cmd.arg("-m").arg("755").arg(TEST_DIR3)).success; - cleanup(TEST_DIR3); - assert_eq!(exit_success, true); -} - -#[test] -fn test_mkdir_parent() { - let mut cmd = Command::new(PROGNAME); - let exit_success = run(&mut cmd.arg("-p").arg(TEST_DIR4)).success; - cleanup(TEST_DIR4); - assert_eq!(exit_success, true); -} - -#[test] -fn test_mkdir_no_parent() { - let mut cmd = Command::new(PROGNAME); - let exit_success = run(&mut cmd.arg(TEST_DIR5)).success; - cleanup(TEST_DIR5); - assert_eq!(exit_success, false); -} diff --git a/test/mv.rs b/test/mv.rs deleted file mode 100644 index 9ab811ae9..000000000 --- a/test/mv.rs +++ /dev/null @@ -1,446 +0,0 @@ -extern crate libc; -extern crate time; -extern crate kernel32; -extern crate winapi; -extern crate filetime; - -use filetime::*; -use std::process::Command; -use util::*; - -static PROGNAME: &'static str = "./mv"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn test_mv_rename_dir() { - let dir1 = "test_mv_rename_dir"; - let dir2 = "test_mv_rename_dir2"; - - mkdir(dir1); - - let result = run(Command::new(PROGNAME).arg(dir1).arg(dir2)); - assert_empty_stderr!(result); - assert!(result.success); - - assert!(dir_exists(dir2)); -} - -#[test] -fn test_mv_rename_file() { - let file1 = "test_mv_rename_file"; - let file2 = "test_mv_rename_file2"; - - touch(file1); - - let result = run(Command::new(PROGNAME).arg(file1).arg(file2)); - assert_empty_stderr!(result); - assert!(result.success); - - assert!(file_exists(file2)); -} - -#[test] -fn test_mv_move_file_into_dir() { - let dir = "test_mv_move_file_into_dir_dir"; - let file = "test_mv_move_file_into_dir_file"; - - mkdir(dir); - touch(file); - - let result = run(Command::new(PROGNAME).arg(file).arg(dir)); - assert_empty_stderr!(result); - assert!(result.success); - - assert!(file_exists(&format!("{}/{}", dir, file))); -} - -#[test] -fn test_mv_strip_slashes() { - let dir = "test_mv_strip_slashes_dir"; - let file = "test_mv_strip_slashes_file"; - let mut source = file.to_owned(); - source.push_str("/"); - - mkdir(dir); - touch(file); - - let result = run(Command::new(PROGNAME).arg(&source).arg(dir)); - assert!(!result.success); - - assert!(!file_exists(&format!("{}/{}", dir, file))); - - let result = run(Command::new(PROGNAME).arg("--strip-trailing-slashes").arg(source).arg(dir)); - assert_empty_stderr!(result); - assert!(result.success); - - assert!(file_exists(&format!("{}/{}", dir, file))); -} - -#[test] -fn test_mv_multiple_files() { - let target_dir = "test_mv_multiple_files_dir"; - let file_a = "test_mv_multiple_file_a"; - let file_b = "test_mv_multiple_file_b"; - - mkdir(target_dir); - touch(file_a); - touch(file_b); - - let result = run(Command::new(PROGNAME).arg(file_a).arg(file_b).arg(target_dir)); - assert_empty_stderr!(result); - assert!(result.success); - - assert!(file_exists(&format!("{}/{}", target_dir, file_a))); - assert!(file_exists(&format!("{}/{}", target_dir, file_b))); -} - -#[test] -fn test_mv_multiple_folders() { - let target_dir = "test_mv_multiple_dirs_dir"; - let dir_a = "test_mv_multiple_dir_a"; - let dir_b = "test_mv_multiple_dir_b"; - - mkdir(target_dir); - mkdir(dir_a); - mkdir(dir_b); - - let result = run(Command::new(PROGNAME).arg(dir_a).arg(dir_b).arg(target_dir)); - assert_empty_stderr!(result); - assert!(result.success); - - assert!(dir_exists(&format!("{}/{}", target_dir, dir_a))); - assert!(dir_exists(&format!("{}/{}", target_dir, dir_b))); -} - -#[test] -fn test_mv_interactive() { - let file_a = "test_mv_interactive_file_a"; - let file_b = "test_mv_interactive_file_b"; - - touch(file_a); - touch(file_b); - - - let result1 = run_piped_stdin(Command::new(PROGNAME).arg("-i").arg(file_a).arg(file_b), b"n"); - - assert_empty_stderr!(result1); - assert!(result1.success); - - assert!(file_exists(file_a)); - assert!(file_exists(file_b)); - - - let result2 = run_piped_stdin(Command::new(PROGNAME).arg("-i").arg(file_a).arg(file_b), b"Yesh"); - - assert_empty_stderr!(result2); - assert!(result2.success); - - assert!(!file_exists(file_a)); - assert!(file_exists(file_b)); -} - -#[test] -fn test_mv_no_clobber() { - let file_a = "test_mv_no_clobber_file_a"; - let file_b = "test_mv_no_clobber_file_b"; - - touch(file_a); - touch(file_b); - - let result = run(Command::new(PROGNAME).arg("-n").arg(file_a).arg(file_b)); - assert_empty_stderr!(result); - assert!(result.success); - - assert!(file_exists(file_a)); - assert!(file_exists(file_b)); -} - -#[test] -fn test_mv_replace_file() { - let file_a = "test_mv_replace_file_a"; - let file_b = "test_mv_replace_file_b"; - - touch(file_a); - touch(file_b); - - let result = run(Command::new(PROGNAME).arg(file_a).arg(file_b)); - assert_empty_stderr!(result); - assert!(result.success); - - assert!(!file_exists(file_a)); - assert!(file_exists(file_b)); -} - -#[test] -fn test_mv_force_replace_file() { - let file_a = "test_mv_force_replace_file_a"; - let file_b = "test_mv_force_replace_file_b"; - - touch(file_a); - touch(file_b); - - let result = run(Command::new(PROGNAME).arg("--force").arg(file_a).arg(file_b)); - assert_empty_stderr!(result); - assert!(result.success); - - assert!(!file_exists(file_a)); - assert!(file_exists(file_b)); -} - -#[test] -fn test_mv_simple_backup() { - let file_a = "test_mv_simple_backup_file_a"; - let file_b = "test_mv_simple_backup_file_b"; - - touch(file_a); - touch(file_b); - let result = run(Command::new(PROGNAME).arg("-b").arg(file_a).arg(file_b)); - - assert_empty_stderr!(result); - assert!(result.success); - - assert!(!file_exists(file_a)); - assert!(file_exists(file_b)); - assert!(file_exists(&format!("{}~", file_b))); -} - -#[test] -fn test_mv_custom_backup_suffix() { - let file_a = "test_mv_custom_backup_suffix_file_a"; - let file_b = "test_mv_custom_backup_suffix_file_b"; - let suffix = "super-suffix-of-the-century"; - - touch(file_a); - touch(file_b); - let result = run(Command::new(PROGNAME) - .arg("-b").arg(format!("--suffix={}", suffix)) - .arg(file_a).arg(file_b)); - - assert_empty_stderr!(result); - assert!(result.success); - - assert!(!file_exists(file_a)); - assert!(file_exists(file_b)); - assert!(file_exists(&format!("{}{}", file_b, suffix))); -} - -#[test] -fn test_mv_backup_numbering() { - let file_a = "test_mv_backup_numbering_file_a"; - let file_b = "test_mv_backup_numbering_file_b"; - - touch(file_a); - touch(file_b); - let result = run(Command::new(PROGNAME).arg("--backup=t").arg(file_a).arg(file_b)); - - assert_empty_stderr!(result); - assert!(result.success); - - assert!(!file_exists(file_a)); - assert!(file_exists(file_b)); - assert!(file_exists(&format!("{}.~1~", file_b))); -} - -#[test] -fn test_mv_existing_backup() { - let file_a = "test_mv_existing_backup_file_a"; - let file_b = "test_mv_existing_backup_file_b"; - let file_b_backup = "test_mv_existing_backup_file_b.~1~"; - let resulting_backup = "test_mv_existing_backup_file_b.~2~"; - - touch(file_a); - touch(file_b); - touch(file_b_backup); - let result = run(Command::new(PROGNAME).arg("--backup=nil").arg(file_a).arg(file_b)); - - assert_empty_stderr!(result); - assert!(result.success); - - assert!(!file_exists(file_a)); - assert!(file_exists(file_b)); - assert!(file_exists(file_b_backup)); - assert!(file_exists(resulting_backup)); -} - -#[test] -fn test_mv_update_option() { - let file_a = "test_mv_update_option_file_a"; - let file_b = "test_mv_update_option_file_b"; - - touch(file_a); - touch(file_b); - let ts = time::now().to_timespec(); - let now = FileTime::from_seconds_since_1970(ts.sec as u64, ts.nsec as u32); - let later = FileTime::from_seconds_since_1970(ts.sec as u64 + 3600, ts.nsec as u32); - filetime::set_file_times(file_a, now, now).unwrap(); - filetime::set_file_times(file_b, now, later).unwrap(); - - let result1 = run(Command::new(PROGNAME).arg("--update").arg(file_a).arg(file_b)); - - assert_empty_stderr!(result1); - assert!(result1.success); - - assert!(file_exists(file_a)); - assert!(file_exists(file_b)); - - let result2 = run(Command::new(PROGNAME).arg("--update").arg(file_b).arg(file_a)); - - assert_empty_stderr!(result2); - assert!(result2.success); - - assert!(file_exists(file_a)); - assert!(!file_exists(file_b)); -} - -#[test] -fn test_mv_target_dir() { - let dir = "test_mv_target_dir_dir"; - let file_a = "test_mv_target_dir_file_a"; - let file_b = "test_mv_target_dir_file_b"; - - touch(file_a); - touch(file_b); - mkdir(dir); - let result = run(Command::new(PROGNAME).arg("-t").arg(dir).arg(file_a).arg(file_b)); - - assert_empty_stderr!(result); - assert!(result.success); - - assert!(!file_exists(file_a)); - assert!(!file_exists(file_b)); - assert!(file_exists(&format!("{}/{}", dir, file_a))); - assert!(file_exists(&format!("{}/{}", dir, file_b))); -} - -#[test] -fn test_mv_overwrite_dir() { - let dir_a = "test_mv_overwrite_dir_a"; - let dir_b = "test_mv_overwrite_dir_b"; - - mkdir(dir_a); - mkdir(dir_b); - let result = run(Command::new(PROGNAME).arg("-T").arg(dir_a).arg(dir_b)); - - assert_empty_stderr!(result); - assert!(result.success); - - assert!(!dir_exists(dir_a)); - assert!(dir_exists(dir_b)); -} - -#[test] -fn test_mv_overwrite_nonempty_dir() { - let dir_a = "test_mv_overwrite_nonempty_dir_a"; - let dir_b = "test_mv_overwrite_nonempty_dir_b"; - let dummy = "test_mv_overwrite_nonempty_dir_b/file"; - - mkdir(dir_a); - mkdir(dir_b); - touch(dummy); - let result = run(Command::new(PROGNAME).arg("-vT").arg(dir_a).arg(dir_b)); - - // Not same error as GNU; the error message is a rust builtin - // TODO: test (and implement) correct error message (or at least decide whether to do so) - // Current: "mv: error: couldn't rename path (Directory not empty; from=a; to=b)" - // GNU: "mv: cannot move ‘a’ to ‘b’: Directory not empty" - assert!(result.stderr.len() > 0); - - // Verbose output for the move should not be shown on failure - assert!(result.stdout.len() == 0); - - assert!(!result.success); - assert!(dir_exists(dir_a)); - assert!(dir_exists(dir_b)); -} - -#[test] -fn test_mv_backup_dir() { - let dir_a = "test_mv_backup_dir_dir_a"; - let dir_b = "test_mv_backup_dir_dir_b"; - - mkdir(dir_a); - mkdir(dir_b); - let result = run(Command::new(PROGNAME).arg("-vbT").arg(dir_a).arg(dir_b)); - - assert_empty_stderr!(result); - assert_eq!(result.stdout, - format!("‘{}’ -> ‘{}’ (backup: ‘{}~’)\n", dir_a, dir_b, dir_b)); - assert!(result.success); - - assert!(!dir_exists(dir_a)); - assert!(dir_exists(dir_b)); - assert!(dir_exists(&format!("{}~", dir_b))); -} - -#[test] -fn test_mv_errors() { - let dir = "test_mv_errors_dir"; - let file_a = "test_mv_errors_file_a"; - let file_b = "test_mv_errors_file_b"; - mkdir(dir); - touch(file_a); - touch(file_b); - - // $ mv -T -t a b - // mv: cannot combine --target-directory (-t) and --no-target-directory (-T) - let result = run(Command::new(PROGNAME).arg("-T").arg("-t").arg(dir).arg(file_a).arg(file_b)); - assert_eq!(result.stderr, - "mv: error: cannot combine --target-directory (-t) and --no-target-directory (-T)\n"); - assert!(!result.success); - - - // $ touch file && mkdir dir - // $ mv -T file dir - // err == mv: cannot overwrite directory ‘dir’ with non-directory - let result = run(Command::new(PROGNAME).arg("-T").arg(file_a).arg(dir)); - assert_eq!(result.stderr, - format!("mv: error: cannot overwrite directory ‘{}’ with non-directory\n", dir)); - assert!(!result.success); - - // $ mkdir dir && touch file - // $ mv dir file - // err == mv: cannot overwrite non-directory ‘file’ with directory ‘dir’ - let result = run(Command::new(PROGNAME).arg(dir).arg(file_a)); - assert!(result.stderr.len() > 0); - assert!(!result.success); -} - -#[test] -fn test_mv_verbose() { - let dir = "test_mv_verbose_dir"; - let file_a = "test_mv_verbose_file_a"; - let file_b = "test_mv_verbose_file_b"; - mkdir(dir); - touch(file_a); - touch(file_b); - - let result = run(Command::new(PROGNAME).arg("-v").arg(file_a).arg(file_b)); - assert_empty_stderr!(result); - assert_eq!(result.stdout, - format!("‘{}’ -> ‘{}’\n", file_a, file_b)); - assert!(result.success); - - - touch(file_a); - let result = run(Command::new(PROGNAME).arg("-vb").arg(file_a).arg(file_b)); - assert_empty_stderr!(result); - assert_eq!(result.stdout, - format!("‘{}’ -> ‘{}’ (backup: ‘{}~’)\n", file_a, file_b, file_b)); - assert!(result.success); -} - -// Todo: - -// $ touch a b -// $ chmod -w b -// $ ll -// total 0 -// -rw-rw-r-- 1 user user 0 okt 25 11:21 a -// -r--r--r-- 1 user user 0 okt 25 11:21 b -// $ -// $ mv -v a b -// mv: try to overwrite ‘b’, overriding mode 0444 (r--r--r--)? y -// ‘a’ -> ‘b’ diff --git a/test/nl.rs b/test/nl.rs deleted file mode 100644 index 29626908a..000000000 --- a/test/nl.rs +++ /dev/null @@ -1,53 +0,0 @@ -use std::process::Command; -use util::*; - -static PROGNAME: &'static str = "./nl"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn test_stdin_nonewline() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd, "No Newline".as_bytes()); - assert_eq!(result.stdout, " 1\tNo Newline\n"); -} -#[test] -fn test_stdin_newline() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-s", "-", "-w", "1"]), "Line One\nLine Two\n".as_bytes()); - assert_eq!(result.stdout, "1-Line One\n2-Line Two\n"); -} - -#[test] -fn test_padding_without_overflow() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.args(&["-i", "1000", "-s", "x", "-n", "rz", "simple.txt"])); - assert_eq!(result.stdout, "000001xL1\n001001xL2\n002001xL3\n003001xL4\n004001xL5\n005001xL6\n006001xL7\n007001xL8\n008001xL9\n009001xL10\n010001xL11\n011001xL12\n012001xL13\n013001xL14\n014001xL15\n"); -} - -#[test] -fn test_padding_with_overflow() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.args(&["-i", "1000", "-s", "x", "-n", "rz", "-w", "4", "simple.txt"])); - assert_eq!(result.stdout, "0001xL1\n1001xL2\n2001xL3\n3001xL4\n4001xL5\n5001xL6\n6001xL7\n7001xL8\n8001xL9\n9001xL10\n10001xL11\n11001xL12\n12001xL13\n13001xL14\n14001xL15\n"); -} - -#[test] -fn test_sections_and_styles() { - for &(fixture, output) in [ - ( - "section.txt", - "\nHEADER1\nHEADER2\n\n1 |BODY1\n2 |BODY2\n\nFOOTER1\nFOOTER2\n\nNEXTHEADER1\nNEXTHEADER2\n\n1 |NEXTBODY1\n2 |NEXTBODY2\n\nNEXTFOOTER1\nNEXTFOOTER2\n" - ), - ( - "joinblanklines.txt", - "1 |Nonempty\n2 |Nonempty\n3 |Followed by 10x empty\n\n\n\n\n4 |\n\n\n\n\n5 |\n6 |Followed by 5x empty\n\n\n\n\n7 |\n8 |Followed by 4x empty\n\n\n\n\n9 |Nonempty\n10 |Nonempty\n11 |Nonempty.\n" - ), - ].iter() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.args(&["-s", "|", "-n", "ln", "-w", "3", "-b", "a", "-l", "5", fixture])); - assert_eq!(result.stdout, output); - } -} diff --git a/test/paste.rs b/test/paste.rs deleted file mode 100644 index b66ed01e7..000000000 --- a/test/paste.rs +++ /dev/null @@ -1,27 +0,0 @@ -use std::fs::File; -use std::io::Read; -use std::path::Path; -use std::process::Command; - -static PROGNAME: &'static str = "./paste"; - -#[test] -fn test_combine_pairs_of_lines() { - let po = Command::new(PROGNAME) - .arg("-s") - .arg("-d") - .arg("\t\n") - .arg("html_colors.txt") - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let mut f = File::open(Path::new("html_colors.expected")).unwrap_or_else(|err| { - panic!("{}", err) - }); - let mut expected = vec!(); - match f.read_to_end(&mut expected) { - Ok(_) => {}, - Err(err) => panic!("{}", err) - } - assert_eq!(String::from_utf8(po.stdout).unwrap(), String::from_utf8(expected).unwrap()); -} diff --git a/test/pwd.rs b/test/pwd.rs deleted file mode 100644 index 0800b3ae4..000000000 --- a/test/pwd.rs +++ /dev/null @@ -1,16 +0,0 @@ -use std::env; -use std::process::Command; -use std::str; - -static PROGNAME: &'static str = "./pwd"; - -#[test] -fn test_default() { - let po = Command::new(PROGNAME) - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right(); - let expected = env::current_dir().unwrap().into_os_string().into_string().unwrap(); - assert_eq!(out, expected); -} diff --git a/test/readlink.rs b/test/readlink.rs deleted file mode 100644 index 6471d1d92..000000000 --- a/test/readlink.rs +++ /dev/null @@ -1,80 +0,0 @@ -use std::process::Command; -use std::str; -use util::*; - -static PROGNAME: &'static str = "./readlink"; -static GIBBERISH: &'static str = "supercalifragilisticexpialidocious"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn test_canonicalize() { - let po = Command::new(PROGNAME) - .arg("-f") - .arg(".") - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right(); - assert_eq!(out, current_directory()); -} - -#[test] -fn test_canonicalize_existing() { - let po = Command::new(PROGNAME) - .arg("-e") - .arg(".") - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right(); - assert_eq!(out, current_directory()); -} - -#[test] -fn test_canonicalize_missing() { - let mut expected = current_directory(); - expected.push_str("/"); - expected.push_str(GIBBERISH); - - let po = Command::new(PROGNAME) - .arg("-m") - .arg(GIBBERISH) - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right(); - assert_eq!(out, expected); -} - -#[test] -fn test_long_redirection_to_current_dir() { - // Create a 256-character path to current directory - let dir = repeat_str("./", 128); - let po = Command::new(PROGNAME) - .arg("-n") - .arg("-m") - .arg(dir) - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap(); - assert_eq!(out, current_directory()); -} - -#[test] -fn test_long_redirection_to_root() { - // Create a 255-character path to root - let dir = repeat_str("../", 85); - let po = Command::new(PROGNAME) - .arg("-n") - .arg("-m") - .arg(dir) - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap(); - assert_eq!(out, "/"); -} diff --git a/test/realpath.rs b/test/realpath.rs deleted file mode 100644 index 53cd539da..000000000 --- a/test/realpath.rs +++ /dev/null @@ -1,46 +0,0 @@ -use std::process::Command; -use std::str; -use util::*; - -static PROGNAME: &'static str = "./realpath"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn test_current_directory() { - let po = Command::new(PROGNAME) - .arg(".") - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right(); - assert_eq!(out, current_directory()); -} - -#[test] -fn test_long_redirection_to_current_dir() { - // Create a 256-character path to current directory - let dir = repeat_str("./", 128); - let po = Command::new(PROGNAME) - .arg(dir) - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right(); - assert_eq!(out, current_directory()); -} - -#[test] -fn test_long_redirection_to_root() { - // Create a 255-character path to root - let dir = repeat_str("../", 85); - let po = Command::new(PROGNAME) - .arg(dir) - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right(); - assert_eq!(out, "/"); -} diff --git a/test/rm.rs b/test/rm.rs deleted file mode 100644 index 5eede78b9..000000000 --- a/test/rm.rs +++ /dev/null @@ -1,140 +0,0 @@ -extern crate libc; - -use std::process::Command; -use util::*; - -static PROGNAME: &'static str = "./rm"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn test_rm_one_file() { - let file = "test_rm_one_file"; - - touch(file); - - let result = run(Command::new(PROGNAME).arg(file)); - assert_empty_stderr!(result); - assert!(result.success); - - assert!(!file_exists(file)); -} - -#[test] -fn test_rm_multiple_files() { - let file_a = "test_rm_multiple_file_a"; - let file_b = "test_rm_multiple_file_b"; - - touch(file_a); - touch(file_b); - - let result = run(Command::new(PROGNAME).arg(file_a).arg(file_b)); - assert_empty_stderr!(result); - assert!(result.success); - - assert!(!file_exists(file_a)); - assert!(!file_exists(file_b)); -} - -#[test] -fn test_rm_interactive() { - let file_a = "test_rm_interactive_file_a"; - let file_b = "test_rm_interactive_file_b"; - - touch(file_a); - touch(file_b); - - let result1 = run_piped_stdin(Command::new(PROGNAME).arg("-i").arg(file_a).arg(file_b), b"n"); - - assert!(result1.success); - - assert!(file_exists(file_a)); - assert!(file_exists(file_b)); - - let result2 = run_piped_stdin(Command::new(PROGNAME).arg("-i").arg(file_a).arg(file_b), b"Yesh"); - - assert!(result2.success); - - assert!(!file_exists(file_a)); - assert!(file_exists(file_b)); -} - -#[test] -fn test_rm_force() { - let file_a = "test_rm_force_a"; - let file_b = "test_rm_force_b"; - - let result = run(Command::new(PROGNAME).arg("-f").arg(file_a).arg(file_b)); - assert_empty_stderr!(result); - assert!(result.success); - - assert!(!file_exists(file_a)); - assert!(!file_exists(file_b)); -} - -#[test] -fn test_rm_empty_directory() { - let dir = "test_rm_empty_directory"; - - mkdir(dir); - - let result = run(Command::new(PROGNAME).arg("-d").arg(dir)); - assert_empty_stderr!(result); - assert!(result.success); - - assert!(!dir_exists(dir)); -} - -#[test] -fn test_rm_recursive() { - let dir = "test_rm_recursive_directory"; - let file_a = "test_rm_recursive_directory/test_rm_recursive_file_a"; - let file_b = "test_rm_recursive_directory/test_rm_recursive_file_b"; - - mkdir(dir); - touch(file_a); - touch(file_b); - - let result = run(Command::new(PROGNAME).arg("-r").arg(dir)); - assert_empty_stderr!(result); - assert!(result.success); - - assert!(!dir_exists(dir)); - assert!(!file_exists(file_a)); - assert!(!file_exists(file_b)); -} - -#[test] -fn test_rm_errors() { - let dir = "test_rm_errors_directory"; - let file_a = "test_rm_errors_directory/test_rm_errors_file_a"; - let file_b = "test_rm_errors_directory/test_rm_errors_file_b"; - - mkdir(dir); - touch(file_a); - touch(file_b); - - // $ rm test_rm_errors_directory - // rm: error: could not remove directory 'test_rm_errors_directory' (did you mean to pass '-r'?) - let result = run(Command::new(PROGNAME).arg(dir)); - assert_eq!(result.stderr, - "rm: error: could not remove directory 'test_rm_errors_directory' (did you mean to pass '-r'?)\n"); - assert!(!result.success); -} - -#[test] -fn test_rm_verbose() { - let file_a = "test_rm_verbose_file_a"; - let file_b = "test_rm_verbose_file_b"; - - touch(file_a); - touch(file_b); - - let result = run(Command::new(PROGNAME).arg("-v").arg(file_a).arg(file_b)); - assert_empty_stderr!(result); - assert_eq!(result.stdout, - format!("removed '{}'\nremoved '{}'\n", file_a, file_b)); - assert!(result.success); -} diff --git a/test/rmdir.rs b/test/rmdir.rs deleted file mode 100644 index d85265d74..000000000 --- a/test/rmdir.rs +++ /dev/null @@ -1,114 +0,0 @@ -extern crate libc; - -use std::process::Command; -use util::*; - -static PROGNAME: &'static str = "./rmdir"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn test_rmdir_empty_directory_no_parents() { - let dir = "test_rmdir_empty_no_parents"; - - mkdir(dir); - assert!(dir_exists(dir)); - - let result = run(Command::new(PROGNAME).arg(dir)); - assert_empty_stderr!(result); - assert!(result.success); - - assert!(!dir_exists(dir)); -} - -#[test] -fn test_rmdir_empty_directory_with_parents() { - let dir = "test_rmdir_empty/with/parents"; - - mkdir_all(dir); - assert!(dir_exists(dir)); - - let result = run(Command::new(PROGNAME).arg("-p").arg(dir)); - assert_empty_stderr!(result); - assert!(result.success); - - assert!(!dir_exists(dir)); -} - -#[test] -fn test_rmdir_nonempty_directory_no_parents() { - let dir = "test_rmdir_nonempty_no_parents"; - let file = "test_rmdir_nonempty_no_parents/foo"; - - mkdir(dir); - assert!(dir_exists(dir)); - - touch(file); - assert!(file_exists(file)); - - let result = run(Command::new(PROGNAME).arg(dir)); - assert_eq!(result.stderr, - "rmdir: error: failed to remove 'test_rmdir_nonempty_no_parents': Directory not empty\n"); - assert!(!result.success); - - assert!(dir_exists(dir)); -} - -#[test] -fn test_rmdir_nonempty_directory_with_parents() { - let dir = "test_rmdir_nonempty/with/parents"; - let file = "test_rmdir_nonempty/with/parents/foo"; - - mkdir_all(dir); - assert!(dir_exists(dir)); - - touch(file); - assert!(file_exists(file)); - - let result = run(Command::new(PROGNAME).arg("-p").arg(dir)); - assert_eq!(result.stderr, - "rmdir: error: failed to remove 'test_rmdir_nonempty/with/parents': Directory not empty\n\ - rmdir: error: failed to remove 'test_rmdir_nonempty/with': Directory not empty\n\ - rmdir: error: failed to remove 'test_rmdir_nonempty': Directory not empty\n"); - assert!(!result.success); - - assert!(dir_exists(dir)); -} - -#[test] -fn test_rmdir_ignore_nonempty_directory_no_parents() { - let dir = "test_rmdir_ignore_nonempty_no_parents"; - let file = "test_rmdir_ignore_nonempty_no_parents/foo"; - - mkdir(dir); - assert!(dir_exists(dir)); - - touch(file); - assert!(file_exists(file)); - - let result = run(Command::new(PROGNAME).arg("--ignore-fail-on-non-empty").arg(dir)); - assert_empty_stderr!(result); - assert!(result.success); - - assert!(dir_exists(dir)); -} - -#[test] -fn test_rmdir_ignore_nonempty_directory_with_parents() { - let dir = "test_rmdir_ignore_nonempty/with/parents"; - let file = "test_rmdir_ignore_nonempty/with/parents/foo"; - - mkdir_all(dir); - assert!(dir_exists(dir)); - - touch(file); - assert!(file_exists(file)); - - let result = run(Command::new(PROGNAME).arg("--ignore-fail-on-non-empty").arg("-p").arg(dir)); - assert_empty_stderr!(result); - assert!(result.success); - - assert!(dir_exists(dir)); -} diff --git a/test/seq.rs b/test/seq.rs deleted file mode 100644 index 806435f33..000000000 --- a/test/seq.rs +++ /dev/null @@ -1,32 +0,0 @@ -use std::process::Command; -use std::str; - -static PROGNAME: &'static str = "./seq"; - -#[test] -fn test_count_up() { - let p = Command::new(PROGNAME).args(&["10"]).output().unwrap(); - let out = str::from_utf8(&p.stdout).unwrap(); - assert_eq!(out, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n"); -} - -#[test] -fn test_count_down() { - let p = Command::new(PROGNAME).args(&["--", "5", "-1", "1"]).output().unwrap(); - let out = str::from_utf8(&p.stdout).unwrap(); - assert_eq!(out, "5\n4\n3\n2\n1\n"); -} - -#[test] -fn test_separator_and_terminator() { - let p = Command::new(PROGNAME).args(&["-s", ",", "-t", "!", "2", "6"]).output().unwrap(); - let out = str::from_utf8(&p.stdout).unwrap(); - assert_eq!(out, "2,3,4,5,6!"); -} - -#[test] -fn test_equalize_widths() { - let p = Command::new(PROGNAME).args(&["-w", "5", "10"]).output().unwrap(); - let out = str::from_utf8(&p.stdout).unwrap(); - assert_eq!(out, "05\n06\n07\n08\n09\n10\n"); -} diff --git a/test/sort.rs b/test/sort.rs deleted file mode 100644 index aa630210c..000000000 --- a/test/sort.rs +++ /dev/null @@ -1,65 +0,0 @@ -use std::fs::File; -use std::io::Read; -use std::path::Path; -use std::process::Command; - -static PROGNAME: &'static str = "./sort"; - -#[test] -fn numeric1() { - numeric_helper(1); -} - -#[test] -fn numeric2() { - numeric_helper(2); -} - -#[test] -fn numeric3() { - numeric_helper(3); -} - -#[test] -fn numeric4() { - numeric_helper(4); -} - -#[test] -fn numeric5() { - numeric_helper(5); -} - -#[test] -fn numeric6() { - numeric_helper(6); -} - -#[test] -fn human1() { - test_helper(&String::from("human1"), &String::from("-H")); -} - -fn numeric_helper(test_num: isize) { - test_helper(&format!("numeric{}", test_num), &String::from("-n")) -} - -fn test_helper(file_name: &String, args: &String) { - let mut cmd = Command::new(PROGNAME); - cmd.arg(args); - let po = match cmd.arg(format!("{}{}", file_name, ".txt")).output() { - Ok(p) => p, - Err(err) => panic!("{}", err) - }; - - let filename = format!("{}{}", file_name, ".ans"); - let mut f = File::open(Path::new(&filename)).unwrap_or_else(|err| { - panic!("{}", err) - }); - let mut answer = vec!(); - match f.read_to_end(&mut answer) { - Ok(_) => {}, - Err(err) => panic!("{}", err) - } - assert_eq!(String::from_utf8(po.stdout).unwrap(), String::from_utf8(answer).unwrap()); -} diff --git a/test/split.rs b/test/split.rs deleted file mode 100644 index 682860100..000000000 --- a/test/split.rs +++ /dev/null @@ -1,160 +0,0 @@ -extern crate libc; -extern crate memchr; -extern crate aho_corasick; -extern crate rand; -extern crate regex_syntax; -extern crate regex; - -use std::fs::{File, read_dir, remove_file}; -use std::io::{Read, Write}; -use std::path::Path; -use std::process::Command; -use rand::{Rng, thread_rng}; -use regex::Regex; -use util::*; - -static PROGNAME: &'static str = "./split"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -fn random_chars(n: usize) -> String { - thread_rng().gen_ascii_chars().take(n).collect::() -} - -struct Glob { - directory: String, - regex: Regex -} - -impl Glob { - fn new(directory: &str, regex: &str) -> Glob { - Glob { - directory: directory.to_string(), - regex: Regex::new(regex).unwrap() - } - } - - fn count(&self) -> usize { - self.collect().len() - } - - fn collect(&self) -> Vec { - read_dir(Path::new(&self.directory)).unwrap().filter_map(|entry| { - let path = entry.unwrap().path(); - let name = path.as_path().to_str().unwrap_or(""); - if self.regex.is_match(name) { Some(name.to_string()) } else { None } - }).collect() - } - - fn collate(&self) -> Vec { - let mut files = self.collect(); - files.sort(); - let mut data: Vec = vec!(); - for name in files.iter() { - data.extend(get_file_contents(name).into_bytes()); - } - data - } - - fn remove_all(&self) { - for name in self.collect().iter() { - let _ = remove_file(name); - } - } -} - -struct RandomFile { - inner: File -} - -impl RandomFile { - fn new(name: &str) -> RandomFile { - RandomFile { inner: File::create(Path::new(name)).unwrap() } - } - - fn add_bytes(&mut self, bytes: usize) { - let chunk_size: usize = if bytes >= 1024 { 1024 } else { bytes }; - let mut n = bytes; - while n > chunk_size { - let _ = write!(self.inner, "{}", random_chars(chunk_size)); - n -= chunk_size; - } - let _ = write!(self.inner, "{}", random_chars(n)); - } - - fn add_lines(&mut self, lines: usize) { - let line_size: usize = 32; - let mut n = lines; - while n > 0 { - let _ = writeln!(self.inner, "{}", random_chars(line_size)); - n -= 1; - } - } -} - -#[test] -fn test_split_default() { - let name = "split_default"; - let glob = Glob::new(".", r"x[:alpha:][:alpha:]$"); - RandomFile::new(name).add_lines(2000); - if !Command::new(PROGNAME).args(&[name]).status().unwrap().success() { - panic!(); - } - assert_eq!(glob.count(), 2); - assert_eq!(glob.collate(), get_file_contents(name).into_bytes()); - glob.remove_all(); -} - -#[test] -fn test_split_num_prefixed_chunks_by_bytes() { - let name = "split_num_prefixed_chunks_by_bytes"; - let glob = Glob::new(".", r"a\d\d$"); - RandomFile::new(name).add_bytes(10000); - if !Command::new(PROGNAME).args(&["-d", "-b", "1000", name, "a"]).status().unwrap().success() { - panic!(); - } - assert_eq!(glob.count(), 10); - assert_eq!(glob.collate(), get_file_contents(name).into_bytes()); - glob.remove_all(); -} - -#[test] -fn test_split_str_prefixed_chunks_by_bytes() { - let name = "split_str_prefixed_chunks_by_bytes"; - let glob = Glob::new(".", r"b[:alpha:][:alpha:]$"); - RandomFile::new(name).add_bytes(10000); - if !Command::new(PROGNAME).args(&["-b", "1000", name, "b"]).status().unwrap().success() { - panic!(); - } - assert_eq!(glob.count(), 10); - assert_eq!(glob.collate(), get_file_contents(name).into_bytes()); - glob.remove_all(); -} - -#[test] -fn test_split_num_prefixed_chunks_by_lines() { - let name = "split_num_prefixed_chunks_by_lines"; - let glob = Glob::new(".", r"c\d\d$"); - RandomFile::new(name).add_lines(10000); - if !Command::new(PROGNAME).args(&["-d", "-l", "1000", name, "c"]).status().unwrap().success() { - panic!(); - } - assert_eq!(glob.count(), 10); - assert_eq!(glob.collate(), get_file_contents(name).into_bytes()); - glob.remove_all(); -} - -#[test] -fn test_split_str_prefixed_chunks_by_lines() { - let name = "split_str_prefixed_chunks_by_lines"; - let glob = Glob::new(".", r"d[:alpha:][:alpha:]$"); - RandomFile::new(name).add_lines(10000); - if !Command::new(PROGNAME).args(&["-l", "1000", name, "d"]).status().unwrap().success() { - panic!(); - } - assert_eq!(glob.count(), 10); - assert_eq!(glob.collate(), get_file_contents(name).into_bytes()); - glob.remove_all(); -} diff --git a/test/stdbuf.rs b/test/stdbuf.rs deleted file mode 100644 index ff7d5259f..000000000 --- a/test/stdbuf.rs +++ /dev/null @@ -1,16 +0,0 @@ -use std::process::Command; -use util::*; - -static PROGNAME: &'static str = "./stdbuf"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn test_stdbuf_unbuffered_stdout() { - // This is a basic smoke test - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-o0", "head"]), "The quick brown fox jumps over the lazy dog."); - assert_eq!(result.stdout, "The quick brown fox jumps over the lazy dog."); -} diff --git a/test/sum.rs b/test/sum.rs deleted file mode 100644 index fb4abbf2d..000000000 --- a/test/sum.rs +++ /dev/null @@ -1,70 +0,0 @@ -use std::process::Command; -use util::*; - -static PROGNAME: &'static str = "./sum"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn test_bsd_single_file() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.arg("lorem_ipsum.txt")); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, get_file_contents("bsd_single_file.expected")); -} - -#[test] -fn test_bsd_multiple_files() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.arg("lorem_ipsum.txt").arg("alice_in_wonderland.txt")); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, get_file_contents("bsd_multiple_files.expected")); -} - -#[test] -fn test_bsd_stdin() { - let input = get_file_contents("lorem_ipsum.txt"); - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd, input); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, get_file_contents("bsd_stdin.expected")); -} - -#[test] -fn test_sysv_single_file() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.arg("-s").arg("lorem_ipsum.txt")); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, get_file_contents("sysv_single_file.expected")); -} - -#[test] -fn test_sysv_multiple_files() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.arg("-s").arg("lorem_ipsum.txt").arg("alice_in_wonderland.txt")); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, get_file_contents("sysv_multiple_files.expected")); -} - -#[test] -fn test_sysv_stdin() { - let input = get_file_contents("lorem_ipsum.txt"); - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.arg("-s"), input); - - assert_empty_stderr!(result); - assert!(result.success); - assert_eq!(result.stdout, get_file_contents("sysv_stdin.expected")); -} diff --git a/test/tac.rs b/test/tac.rs deleted file mode 100644 index 5ec5a26b4..000000000 --- a/test/tac.rs +++ /dev/null @@ -1,50 +0,0 @@ -use std::process::Command; -use util::*; - -static PROGNAME: &'static str = "./tac"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn test_stdin_default() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd, "100\n200\n300\n400\n500"); - assert_eq!(result.stdout, "500400\n300\n200\n100\n"); -} - -#[test] -fn test_stdin_non_newline_separator() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-s", ":"]), "100:200:300:400:500"); - assert_eq!(result.stdout, "500400:300:200:100:"); -} - -#[test] -fn test_stdin_non_newline_separator_before() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-b", "-s", ":"]), "100:200:300:400:500"); - assert_eq!(result.stdout, "500:400:300:200:100"); -} - -#[test] -fn test_single_default() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.arg("prime_per_line.txt")); - assert_eq!(result.stdout, get_file_contents("prime_per_line.expected")); -} - -#[test] -fn test_single_non_newline_separator() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.args(&["-s", ":", "delimited_primes.txt"])); - assert_eq!(result.stdout, get_file_contents("delimited_primes.expected")); -} - -#[test] -fn test_single_non_newline_separator_before() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.args(&["-b", "-s", ":", "delimited_primes.txt"])); - assert_eq!(result.stdout, get_file_contents("delimited_primes_before.expected")); -} diff --git a/test/test.rs b/test/test.rs deleted file mode 100644 index af6758ae6..000000000 --- a/test/test.rs +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of the uutils coreutils package. - * - * (c) mahkoh (ju.orth [at] gmail [dot] com) - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use std::process::Command; - -static PROGNAME: &'static str = "./test"; - -#[test] -fn test_op_prec_and_or_1() { - let status = Command::new(PROGNAME).arg(" ").arg("-o").arg("").arg("-a").arg("").status(); - assert_eq!(true, status.unwrap().success()); -} - -#[test] -fn test_op_prec_and_or_2() { - let status = Command::new(PROGNAME).arg("") - .arg("-a") - .arg("") - .arg("-o") - .arg(" ") - .arg("-a") - .arg(" ") - .status(); - assert_eq!(true, status.unwrap().success()); -} - -#[test] -fn test_or_as_filename() { - let status = Command::new(PROGNAME).arg("x").arg("-a").arg("-z").arg("-o").status(); - assert_eq!(status.unwrap().code(), Some(1)); -} diff --git a/test/tr.rs b/test/tr.rs deleted file mode 100644 index 3da1b9605..000000000 --- a/test/tr.rs +++ /dev/null @@ -1,43 +0,0 @@ -use std::process::Command; -use util::*; - -static PROGNAME: &'static str = "./tr"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn test_toupper() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["a-z", "A-Z"]), b"!abcd!"); - assert_eq!(result.stdout, "!ABCD!"); -} - -#[test] -fn test_small_set2() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["0-9", "X"]), b"@0123456789"); - assert_eq!(result.stdout, "@XXXXXXXXXX"); -} - -#[test] -fn test_unicode() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&[", ┬─┬", "╯︵┻━┻"]), "(,°□°), ┬─┬".as_bytes()); - assert_eq!(result.stdout, "(╯°□°)╯︵┻━┻"); -} - -#[test] -fn test_delete() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-d", "a-z"]), b"aBcD"); - assert_eq!(result.stdout, "BD"); -} - -#[test] -fn test_delete_complement() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-d", "-c", "a-z"]), b"aBcD"); - assert_eq!(result.stdout, "ac"); -} diff --git a/test/true.rs b/test/true.rs deleted file mode 100644 index fba9fff36..000000000 --- a/test/true.rs +++ /dev/null @@ -1,9 +0,0 @@ -use std::process::Command; - -static PROGNAME: &'static str = "./true"; - -#[test] -fn test_exit_code() { - let exit_status = Command::new(PROGNAME).status().unwrap().success(); - assert_eq!(exit_status, true); -} diff --git a/test/truncate.rs b/test/truncate.rs deleted file mode 100644 index 3461fcbf9..000000000 --- a/test/truncate.rs +++ /dev/null @@ -1,41 +0,0 @@ -use std::fs; -use std::io::{Seek, SeekFrom, Write}; -use std::path::Path; -use std::process::Command; -use util::*; - -static PROGNAME: &'static str = "./truncate"; -static TFILE1: &'static str = "truncate_test_1"; -static TFILE2: &'static str = "truncate_test_2"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn test_increase_file_size() { - let mut file = make_file(TFILE1); - if !Command::new(PROGNAME).args(&["-s", "+5K", TFILE1]).status().unwrap().success() { - panic!(); - } - file.seek(SeekFrom::End(0)).unwrap(); - if file.seek(SeekFrom::Current(0)).unwrap() != 5 * 1024 { - panic!(); - } - fs::remove_file(Path::new(TFILE1)).unwrap(); -} - -#[test] -fn test_decrease_file_size() { - let mut file = make_file(TFILE2); - file.write_all(b"1234567890").unwrap(); - if !Command::new(PROGNAME).args(&["--size=-4", TFILE2]).status().unwrap().success() { - panic!(); - } - file.seek(SeekFrom::End(0)).unwrap(); - if file.seek(SeekFrom::Current(0)).unwrap() != 6 { - println!("{:?}", file.seek(SeekFrom::Current(0))); - panic!(); - } - fs::remove_file(Path::new(TFILE2)).unwrap(); -} diff --git a/test/tsort.rs b/test/tsort.rs deleted file mode 100644 index 18648f3ad..000000000 --- a/test/tsort.rs +++ /dev/null @@ -1,21 +0,0 @@ -use std::process::Command; -use util::*; - -static PROGNAME: &'static str = "./tsort"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn test_sort_call_graph() { - let input = "call_graph.txt"; - let output = "call_graph.expected"; - - let po = Command::new(PROGNAME) - .arg(input) - .output() - .unwrap_or_else(|err| panic!("{}", err)); - - assert_eq!(String::from_utf8(po.stdout).unwrap(), String::from_utf8(get_file_contents(output).into_bytes()).unwrap()); -} diff --git a/test/unexpand.rs b/test/unexpand.rs deleted file mode 100644 index c68057730..000000000 --- a/test/unexpand.rs +++ /dev/null @@ -1,115 +0,0 @@ -use std::process::Command; -use util::*; - -static PROGNAME: &'static str = "./unexpand"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn unexpand_init_0() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-t4"]), " 1\n 2\n 3\n 4\n"); - assert_eq!(result.stdout, " 1\n 2\n 3\n\t4\n"); -} - -#[test] -fn unexpand_init_1() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-t4"]), " 5\n 6\n 7\n 8\n"); - assert_eq!(result.stdout, "\t 5\n\t 6\n\t 7\n\t\t8\n"); -} - -#[test] -fn unexpand_init_list_0() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-t2,4"]), " 1\n 2\n 3\n 4\n"); - assert_eq!(result.stdout, " 1\n\t2\n\t 3\n\t\t4\n"); -} - -#[test] -fn unexpand_init_list_1() { - // Once the list is exhausted, spaces are not converted anymore - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-t2,4"]), " 5\n 6\n 7\n 8\n"); - assert_eq!(result.stdout, "\t\t 5\n\t\t 6\n\t\t 7\n\t\t 8\n"); -} - -#[test] -fn unexpand_aflag_0() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["--"]), "e E\nf F\ng G\nh H\n"); - assert_eq!(result.stdout, "e E\nf F\ng G\nh H\n"); -} - -#[test] -fn unexpand_aflag_1() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-a"]), "e E\nf F\ng G\nh H\n"); - assert_eq!(result.stdout, "e E\nf F\ng\tG\nh\t H\n"); -} - -#[test] -fn unexpand_aflag_2() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-t8"]), "e E\nf F\ng G\nh H\n"); - assert_eq!(result.stdout, "e E\nf F\ng\tG\nh\t H\n"); -} - -#[test] -fn unexpand_first_only_0() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-t3"]), " A B"); - assert_eq!(result.stdout, "\t\t A\t B"); -} - -#[test] -fn unexpand_first_only_1() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-t3", "--first-only"]), " A B"); - assert_eq!(result.stdout, "\t\t A B"); -} - -#[test] -fn unexpand_trailing_space_0() { // evil - // Individual spaces before fields starting with non blanks should not be - // converted, unless they are at the beginning of the line. - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-t4"]), "123 \t1\n123 1\n123 \n123 "); - assert_eq!(result.stdout, "123\t\t1\n123 1\n123 \n123 "); -} - -#[test] -fn unexpand_trailing_space_1() { // super evil - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-t1"]), " abc d e f g "); - assert_eq!(result.stdout, "\tabc d e\t\tf\t\tg "); -} - -#[test] -fn unexpand_spaces_follow_tabs_0() { - // The two first spaces can be included into the first tab. - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd, " \t\t A"); - assert_eq!(result.stdout, "\t\t A"); -} - -#[test] -fn unexpand_spaces_follow_tabs_1() { // evil - // Explanation of what is going on here: - // 'a' -> 'a' // first tabstop (1) - // ' \t' -> '\t' // second tabstop (4) - // ' ' -> '\t' // third tabstop (5) - // ' B \t' -> ' B \t' // after the list is exhausted, nothing must change - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-t1,4,5"]), "a \t B \t"); - assert_eq!(result.stdout, "a\t\t B \t"); -} - -#[test] -fn unexpand_spaces_after_fields() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-a"]), " \t A B C D A\t\n"); - assert_eq!(result.stdout, "\t\tA B C D\t\t A\t\n"); -} diff --git a/test/unlink.rs b/test/unlink.rs deleted file mode 100644 index 1d18d9baf..000000000 --- a/test/unlink.rs +++ /dev/null @@ -1,59 +0,0 @@ -extern crate libc; - -use std::process::Command; -use util::*; - -static PROGNAME: &'static str = "./unlink"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn test_unlink_file() { - let file = "test_unlink_file"; - - touch(file); - - let result = run(Command::new(PROGNAME).arg(file)); - assert_empty_stderr!(result); - assert!(result.success); - - assert!(!file_exists(file)); -} - -#[test] -fn test_unlink_multiple_files() { - let file_a = "test_unlink_multiple_file_a"; - let file_b = "test_unlink_multiple_file_b"; - - touch(file_a); - touch(file_b); - - let result = run(Command::new(PROGNAME).arg(file_a).arg(file_b)); - assert_eq!(result.stderr, - "unlink: error: extra operand: 'test_unlink_multiple_file_b'\nTry 'unlink --help' for more information.\n"); - assert!(!result.success); -} - -#[test] -fn test_unlink_directory() { - let dir = "test_unlink_empty_directory"; - - mkdir(dir); - - let result = run(Command::new(PROGNAME).arg(dir)); - assert_eq!(result.stderr, - "unlink: error: cannot unlink 'test_unlink_empty_directory': Not a regular file or symlink\n"); - assert!(!result.success); -} - -#[test] -fn test_unlink_nonexistent() { - let file = "test_unlink_nonexistent"; - - let result = run(Command::new(PROGNAME).arg(file)); - assert_eq!(result.stderr, - "unlink: error: Cannot stat 'test_unlink_nonexistent': No such file or directory (os error 2)\n"); - assert!(!result.success); -} diff --git a/test/wc.rs b/test/wc.rs deleted file mode 100644 index 5cb8f3b59..000000000 --- a/test/wc.rs +++ /dev/null @@ -1,57 +0,0 @@ -use std::process::Command; -use util::*; - -static PROGNAME: &'static str = "./wc"; - -#[path = "common/util.rs"] -#[macro_use] -mod util; - -#[test] -fn test_stdin_default() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd, get_file_contents("lorem_ipsum.txt")); - assert_eq!(result.stdout, " 13 109 772\n"); -} - -#[test] -fn test_stdin_only_bytes() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-c"]), get_file_contents("lorem_ipsum.txt")); - assert_eq!(result.stdout, " 772\n"); -} - -#[test] -fn test_stdin_all_counts() { - let mut cmd = Command::new(PROGNAME); - let result = run_piped_stdin(&mut cmd.args(&["-c", "-m", "-l", "-L", "-w"]), get_file_contents("alice_in_wonderland.txt")); - assert_eq!(result.stdout, " 5 57 302 302 66\n"); -} - -#[test] -fn test_single_default() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.arg("moby_dick.txt")); - assert_eq!(result.stdout, " 18 204 1115 moby_dick.txt\n"); -} - -#[test] -fn test_single_only_lines() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.args(&["-l", "moby_dick.txt"])); - assert_eq!(result.stdout, " 18 moby_dick.txt\n"); -} - -#[test] -fn test_single_all_counts() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.args(&["-c", "-l", "-L", "-m", "-w", "alice_in_wonderland.txt"])); - assert_eq!(result.stdout, " 5 57 302 302 66 alice_in_wonderland.txt\n"); -} - -#[test] -fn test_multiple_default() { - let mut cmd = Command::new(PROGNAME); - let result = run(&mut cmd.args(&["lorem_ipsum.txt", "moby_dick.txt", "alice_in_wonderland.txt"])); - assert_eq!(result.stdout, " 13 109 772 lorem_ipsum.txt\n 18 204 1115 moby_dick.txt\n 5 57 302 alice_in_wonderland.txt\n 36 370 2189 total\n"); -} diff --git a/tests/base64.rs b/tests/base64.rs new file mode 100644 index 000000000..bfa23edec --- /dev/null +++ b/tests/base64.rs @@ -0,0 +1,62 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "base64"; + +#[test] +fn test_encode() { + let (_, mut ucmd) = testing(UTIL_NAME); + let input = "hello, world!"; + let result = ucmd.run_piped_stdin(input.as_bytes()); + + assert_empty_stderr!(result); + assert!(result.success); + assert_eq!(result.stdout, "aGVsbG8sIHdvcmxkIQ==\n"); +} + +#[test] +fn test_decode() { + let (_, mut ucmd) = testing(UTIL_NAME); + let input = "aGVsbG8sIHdvcmxkIQ=="; + let result = ucmd.arg("-d").run_piped_stdin(input.as_bytes()); + + assert_empty_stderr!(result); + assert!(result.success); + assert_eq!(result.stdout, "hello, world!"); +} + +#[test] +fn test_garbage() { + let (_, mut ucmd) = testing(UTIL_NAME); + let input = "aGVsbG8sIHdvcmxkIQ==\0"; + let result = ucmd.arg("-d").run_piped_stdin(input.as_bytes()); + + assert!(!result.success); + assert_eq!(result.stderr, + "base64: error: invalid character (Invalid character '0' at position 20)\n"); +} + +#[test] +fn test_ignore_garbage() { + let (_, mut ucmd) = testing(UTIL_NAME); + let input = "aGVsbG8sIHdvcmxkIQ==\0"; + let result = ucmd.arg("-d").arg("-i").run_piped_stdin(input.as_bytes()); + + assert_empty_stderr!(result); + assert!(result.success); + assert_eq!(result.stdout, "hello, world!"); +} + +#[test] +fn test_wrap() { + let (_, mut ucmd) = testing(UTIL_NAME); + let input = "The quick brown fox jumps over the lazy dog."; + let result = ucmd.arg("-w").arg("20").run_piped_stdin(input.as_bytes()); + + assert_empty_stderr!(result); + assert!(result.success); + assert_eq!(result.stdout, + "VGhlIHF1aWNrIGJyb3du\nIGZveCBqdW1wcyBvdmVy\nIHRoZSBsYXp5IGRvZy4=\n"); +} diff --git a/tests/basename.rs b/tests/basename.rs new file mode 100644 index 000000000..ec5decad4 --- /dev/null +++ b/tests/basename.rs @@ -0,0 +1,44 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "basename"; + +#[test] +fn test_directory() { + let (_, mut ucmd) = testing(UTIL_NAME); + let dir = "/root/alpha/beta/gamma/delta/epsilon/omega/"; + ucmd.arg(dir); + + assert_eq!(ucmd.run().stdout.trim_right(), "omega"); +} + +#[test] +fn test_file() { + let (_, mut ucmd) = testing(UTIL_NAME); + let file = "/etc/passwd"; + ucmd.arg(file); + + assert_eq!(ucmd.run().stdout.trim_right(), "passwd"); +} + +#[test] +fn test_remove_suffix() { + let (_, mut ucmd) = testing(UTIL_NAME); + let path = "/usr/local/bin/reallylongexecutable.exe"; + ucmd.arg(path) + .arg(".exe"); + + assert_eq!(ucmd.run().stdout.trim_right(), "reallylongexecutable"); +} + +#[test] +fn test_dont_remove_suffix() { + let (_, mut ucmd) = testing(UTIL_NAME); + let path = "/foo/bar/baz"; + ucmd.arg(path) + .arg("baz"); + + assert_eq!(ucmd.run().stdout.trim_right(), "baz"); +} diff --git a/tests/cat.rs b/tests/cat.rs new file mode 100644 index 000000000..8b55cfc5f --- /dev/null +++ b/tests/cat.rs @@ -0,0 +1,49 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "cat"; + +#[test] +fn test_output_multi_files_print_all_chars() { + let (_, mut ucmd) = testing(UTIL_NAME); + ucmd.arg("alpha.txt") + .arg("256.txt") + .arg("-A") + .arg("-n"); + + assert_eq!(ucmd.run().stdout, + " 1\tabcde$\n 2\tfghij$\n 3\tklmno$\n 4\tpqrst$\n \ + 5\tuvwxyz$\n 6\t^@^A^B^C^D^E^F^G^H^I$\n \ + 7\t^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z^[^\\^]^^^_ \ + !\"#$%&\'()*+,-./0123456789:;\ + <=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~^?M-^@M-^AM-^\ + BM-^CM-^DM-^EM-^FM-^GM-^HM-^IM-^JM-^KM-^LM-^MM-^NM-^OM-^PM-^QM-^RM-^SM-^TM-^UM-^V\ + M-^WM-^XM-^YM-^ZM-^[M-^\\M-^]M-^^M-^_M- \ + M-!M-\"M-#M-$M-%M-&M-\'M-(M-)M-*M-+M-,M--M-.M-/M-0M-1M-2M-3M-4M-5M-6M-7M-8M-9M-:\ + M-;M-M-?M-@M-AM-BM-CM-DM-EM-FM-GM-HM-IM-JM-KM-LM-MM-NM-OM-PM-QM-RM-SM-TM-U\ + M-VM-WM-XM-YM-ZM-[M-\\M-]M-^M-_M-`M-aM-bM-cM-dM-eM-fM-gM-hM-iM-jM-kM-lM-mM-nM-oM-\ + pM-qM-rM-sM-tM-uM-vM-wM-xM-yM-zM-{M-|M-}M-~M-^?"); +} + +#[test] +fn test_stdin_squeeze() { + let (_, mut ucmd) = testing(UTIL_NAME); + let out = ucmd.arg("-A") + .run_piped_stdin("\x00\x01\x02".as_bytes()) + .stdout; + + assert_eq!(out, "^@^A^B"); +} + +#[test] +fn test_stdin_number_non_blank() { + let (_, mut ucmd) = testing(UTIL_NAME); + let out = ucmd.arg("-b") + .arg("-") + .run_piped_stdin("\na\nb\n\n\nc".as_bytes()) + .stdout; + + assert_eq!(out, "\n 1\ta\n 2\tb\n\n\n 3\tc"); +} diff --git a/tests/cksum.rs b/tests/cksum.rs new file mode 100644 index 000000000..f41b569d8 --- /dev/null +++ b/tests/cksum.rs @@ -0,0 +1,39 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "cksum"; + +#[test] +fn test_single_file() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.arg("lorem_ipsum.txt").run(); + + assert_empty_stderr!(result); + assert!(result.success); + assert_eq!(result.stdout, at.read("single_file.expected")); +} + +#[test] +fn test_multiple_files() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.arg("lorem_ipsum.txt") + .arg("alice_in_wonderland.txt") + .run(); + + assert_empty_stderr!(result); + assert!(result.success); + assert_eq!(result.stdout, at.read("multiple_files.expected")); +} + +#[test] +fn test_stdin() { + let (at, mut ucmd) = testing(UTIL_NAME); + let input = at.read("lorem_ipsum.txt"); + let result = ucmd.run_piped_stdin(input); + + assert_empty_stderr!(result); + assert!(result.success); + assert_eq!(result.stdout, at.read("stdin.expected")); +} diff --git a/tests/common/mod.rs b/tests/common/mod.rs new file mode 100644 index 000000000..870edd9ff --- /dev/null +++ b/tests/common/mod.rs @@ -0,0 +1,2 @@ +#[macro_use] +pub mod util; diff --git a/tests/common/util.rs b/tests/common/util.rs new file mode 100644 index 000000000..6debdc775 --- /dev/null +++ b/tests/common/util.rs @@ -0,0 +1,354 @@ +#![allow(dead_code)] + +extern crate tempdir; + +use std::env; +use std::fs::{self, File}; +use std::io::{Read, Write, Result}; +#[cfg(unix)] +use std::os::unix::fs::symlink as symlink_file; +#[cfg(windows)] +use std::os::windows::fs::symlink_file; +use std::path::{Path, PathBuf}; +use std::process::{Command, Stdio}; +use std::str::from_utf8; +use std::ffi::OsStr; +use self::tempdir::TempDir; +use std::rc::Rc; + +static PROGNAME: &'static str = "target/debug/uutils"; +static FIXTURES_DIR: &'static str = "tests/fixtures"; +static ALREADY_RUN: &'static str = " you have already run this UCommand, if you want to run \ + another command in the same test, use TestSet::new instead of \ + testing();"; + +#[macro_export] +macro_rules! assert_empty_stderr( + ($cond:expr) => ( + if $cond.stderr.len() > 0 { + panic!(format!("stderr: {}", $cond.stderr)) + } + ); +); + +#[macro_export] +macro_rules! assert_no_error( + ($cond:expr) => ( + assert!($cond.success); + if $cond.stderr.len() > 0 { + panic!(format!("stderr: {}", $cond.stderr)) + } + ); +); + +pub struct CmdResult { + pub success: bool, + pub stdout: String, + pub stderr: String, +} + +pub fn log_info, U: AsRef>(msg: T, par: U) { + println!("{}: {}", msg.as_ref(), par.as_ref()); +} + + +pub fn repeat_str(s: &str, n: u32) -> String { + let mut repeated = String::new(); + for _ in 0..n { + repeated.push_str(s); + } + repeated +} + +pub fn recursive_copy(src: &Path, dest: &Path) -> Result<()> { + if try!(fs::metadata(src)).is_dir() { + for entry in try!(fs::read_dir(src)) { + let entry = try!(entry); + let mut new_dest = PathBuf::from(dest); + new_dest.push(entry.file_name()); + if try!(fs::metadata(entry.path())).is_dir() { + try!(fs::create_dir(&new_dest)); + try!(recursive_copy(&entry.path(), &new_dest)); + } else { + try!(fs::copy(&entry.path(), new_dest)); + } + } + } + Ok(()) +} + +pub struct AtPath { + pub subdir: PathBuf, +} +impl AtPath { + pub fn new(subdir: &Path) -> AtPath { + AtPath { subdir: PathBuf::from(subdir) } + } + pub fn as_string(&self) -> String { + self.subdir.to_str().unwrap().to_owned() + } + pub fn plus(&self, name: &str) -> PathBuf { + let mut pathbuf = self.subdir.clone(); + pathbuf.push(name); + pathbuf + } + pub fn plus_as_string(&self, name: &str) -> String { + String::from(self.plus(name).to_str().unwrap()) + } + fn minus(&self, name: &str) -> PathBuf { + // relative_from is currently unstable + let prefixed = PathBuf::from(name); + if prefixed.starts_with(&self.subdir) { + let mut unprefixed = PathBuf::new(); + for component in prefixed.components() + .skip(self.subdir.components().count()) { + unprefixed.push(component.as_ref().to_str().unwrap()); + } + unprefixed + } else { + prefixed + } + } + pub fn minus_as_string(&self, name: &str) -> String { + String::from(self.minus(name).to_str().unwrap()) + } + pub fn open(&self, name: &str) -> File { + log_info("open", self.plus_as_string(name)); + File::open(self.plus(name)).unwrap() + } + pub fn read(&self, name: &str) -> String { + let mut f = self.open(name); + let mut contents = String::new(); + let _ = f.read_to_string(&mut contents); + contents + } + pub fn write(&self, name: &str, contents: &str) { + let mut f = self.open(name); + let _ = f.write(contents.as_bytes()); + } + pub fn mkdir(&self, dir: &str) { + log_info("mkdir", self.plus_as_string(dir)); + fs::create_dir(&self.plus(dir)).unwrap(); + } + pub fn mkdir_all(&self, dir: &str) { + log_info("mkdir_all", self.plus_as_string(dir)); + fs::create_dir_all(self.plus(dir)).unwrap(); + } + pub fn make_file(&self, name: &str) -> File { + match File::create(&self.plus(name)) { + Ok(f) => f, + Err(e) => panic!("{}", e), + } + } + pub fn touch(&self, file: &str) { + log_info("touch", self.plus_as_string(file)); + File::create(&self.plus(file)).unwrap(); + } + pub fn symlink(&self, src: &str, dst: &str) { + log_info("symlink", + &format!("{},{}", self.plus_as_string(src), self.plus_as_string(dst))); + symlink_file(&self.plus(src), &self.plus(dst)).unwrap(); + } + pub fn is_symlink(&self, path: &str) -> bool { + log_info("is_symlink", self.plus_as_string(path)); + match fs::symlink_metadata(&self.plus(path)) { + Ok(m) => m.file_type().is_symlink(), + Err(_) => false, + } + } + + pub fn resolve_link(&self, path: &str) -> String { + log_info("resolve_link", self.plus_as_string(path)); + match fs::read_link(&self.plus(path)) { + Ok(p) => { + self.minus_as_string(p.to_str().unwrap()) + } + Err(_) => "".to_string(), + } + } + + pub fn metadata(&self, path: &str) -> fs::Metadata { + match fs::metadata(&self.plus(path)) { + Ok(m) => m, + Err(e) => panic!("{}", e), + } + } + + pub fn file_exists(&self, path: &str) -> bool { + match fs::metadata(&self.plus(path)) { + Ok(m) => m.is_file(), + Err(_) => false, + } + } + + pub fn dir_exists(&self, path: &str) -> bool { + match fs::metadata(&self.plus(path)) { + Ok(m) => m.is_dir(), + Err(_) => false, + } + } + + pub fn cleanup(&self, path: &'static str) { + let p = &self.plus(path); + match fs::metadata(p) { + Ok(m) => if m.is_file() { + fs::remove_file(&p).unwrap(); + } else { + fs::remove_dir(&p).unwrap(); + }, + Err(_) => {} + } + } + pub fn root_dir(&self) -> String { + log_info("current_directory", ""); + self.subdir.to_str().unwrap().to_owned() + } +} + +pub struct TestSet { + bin_path: PathBuf, + util_name: String, + pub fixtures: AtPath, + tmpd: Rc, +} +impl TestSet { + pub fn new(util_name: &str) -> TestSet { + let tmpd = Rc::new(TempDir::new("uutils").unwrap()); + let ts = TestSet { + bin_path: { + let mut bin_path_builder = env::current_dir().unwrap(); + bin_path_builder.push(PathBuf::from(PROGNAME)); + bin_path_builder + }, + util_name: String::from(util_name), + fixtures: AtPath::new(&tmpd.as_ref().path()), + tmpd: tmpd, + }; + let mut fixture_path_builder = env::current_dir().unwrap(); + fixture_path_builder.push(PathBuf::from(FIXTURES_DIR)); + fixture_path_builder.push(PathBuf::from(util_name)); + match fs::metadata(&fixture_path_builder) { + Ok(m) => if m.is_dir() { + recursive_copy(&fixture_path_builder, &ts.fixtures.subdir).unwrap(); + }, + Err(_) => {} + } + ts + } + pub fn util_cmd(&self) -> UCommand { + let mut cmd = self.cmd(&self.bin_path); + cmd.arg(&self.util_name); + cmd + } + pub fn cmd>(&self, bin: S) -> UCommand { + UCommand::new_from_tmp(bin, self.tmpd.clone(), true) + } + // different names are used rather than an argument + // because the need to keep the environment is exceedingly rare. + pub fn util_cmd_keepenv(&self) -> UCommand { + let mut cmd = self.cmd_keepenv(&self.bin_path); + cmd.arg(&self.util_name); + cmd + } + pub fn cmd_keepenv>(&self, bin: S) -> UCommand { + UCommand::new_from_tmp(bin, self.tmpd.clone(), false) + } +} + +pub struct UCommand { + pub raw: Command, + comm_string: String, + tmpd: Option>, + has_run: bool, +} +impl UCommand { + pub fn new, U: AsRef>(arg: T, curdir: U, env_clear: bool) -> UCommand { + UCommand { + tmpd: None, + has_run: false, + raw: { + let mut cmd = Command::new(arg.as_ref()); + cmd.current_dir(curdir.as_ref()); + if env_clear { + cmd.env_clear(); + } + cmd + }, + comm_string: String::from(arg.as_ref().to_str().unwrap()), + } + } + pub fn new_from_tmp>(arg: T, tmpd: Rc, env_clear: bool) -> UCommand { + let tmpd_path_buf = String::from(&(*tmpd.as_ref().path().to_str().unwrap())); + let mut ucmd: UCommand = UCommand::new(arg.as_ref(), tmpd_path_buf, env_clear); + ucmd.tmpd = Some(tmpd); + ucmd + } + pub fn arg>(&mut self, arg: S) -> Box<&mut UCommand> { + if self.has_run { + panic!(ALREADY_RUN); + } + self.comm_string.push_str(" "); + self.comm_string.push_str(arg.as_ref().to_str().unwrap()); + self.raw.arg(arg.as_ref()); + Box::new(self) + } + + pub fn args>(&mut self, args: &[S]) -> Box<&mut UCommand> { + if self.has_run { + panic!(ALREADY_RUN); + } + for s in args { + self.comm_string.push_str(" "); + self.comm_string.push_str(s.as_ref().to_str().unwrap()); + } + + self.raw.args(args.as_ref()); + Box::new(self) + } + pub fn run(&mut self) -> CmdResult { + self.has_run = true; + log_info("run", &self.comm_string); + let prog = self.raw.output().unwrap(); + CmdResult { + success: prog.status.success(), + stdout: from_utf8(&prog.stdout).unwrap().to_string(), + stderr: from_utf8(&prog.stderr).unwrap().to_string(), + } + } + pub fn run_piped_stdin>(&mut self, input: T) -> CmdResult { + self.has_run = true; + log_info("run_piped_stdin", &self.comm_string); + let mut result = self.raw + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .unwrap(); + + result.stdin + .take() + .unwrap_or_else(|| panic!("Could not take child process stdin")) + .write_all(input.as_ref()) + .unwrap_or_else(|e| panic!("{}", e)); + + let prog = result.wait_with_output().unwrap(); + CmdResult { + success: prog.status.success(), + stdout: from_utf8(&prog.stdout).unwrap().to_string(), + stderr: from_utf8(&prog.stderr).unwrap().to_string(), + } + } +} + +// returns a testSet and a ucommand initialized to the utility binary +// operating in the fixtures directory with a cleared environment +pub fn testset_and_ucommand(utilname: &str) -> (TestSet, UCommand) { + let ts = TestSet::new(utilname); + let ucmd = ts.util_cmd(); + (ts, ucmd) +} +pub fn testing(utilname: &str) -> (AtPath, UCommand) { + let ts = TestSet::new(utilname); + let ucmd = ts.util_cmd(); + (ts.fixtures, ucmd) +} diff --git a/tests/cp.rs b/tests/cp.rs new file mode 100644 index 000000000..4e3089314 --- /dev/null +++ b/tests/cp.rs @@ -0,0 +1,25 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "cp"; + +static TEST_HELLO_WORLD_SOURCE: &'static str = "hello_world.txt"; +static TEST_HELLO_WORLD_DEST: &'static str = "copy_of_hello_world.txt"; + +#[test] +fn test_cp_cp() { + let (at, mut ucmd) = testing(UTIL_NAME); + // Invoke our binary to make the copy. + let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE) + .arg(TEST_HELLO_WORLD_DEST) + .run(); + + // Check that the exit code represents a successful copy. + let exit_success = result.success; + assert_eq!(exit_success, true); + + // Check the content of the destination file that was copied. + assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n"); +} diff --git a/tests/cut.rs b/tests/cut.rs new file mode 100644 index 000000000..216513f8a --- /dev/null +++ b/tests/cut.rs @@ -0,0 +1,60 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "cut"; + +static INPUT: &'static str = "lists.txt"; + + +#[test] +fn test_prefix() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-c", "-10", INPUT]).run(); + assert_eq!(result.stdout, at.read("lists_prefix.expected")); +} + +#[test] +fn test_char_range() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-c", "4-10", INPUT]).run(); + assert_eq!(result.stdout, at.read("lists_char_range.expected")); +} + +#[test] +fn test_column_to_end_of_line() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-d", ":", "-f", "5-", INPUT]).run(); + assert_eq!(result.stdout, + at.read("lists_column_to_end_of_line.expected")); +} + +#[test] +fn test_specific_field() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-d", " ", "-f", "3", INPUT]).run(); + assert_eq!(result.stdout, at.read("lists_specific_field.expected")); +} + +#[test] +fn test_multiple_fields() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-d", ":", "-f", "1,3", INPUT]).run(); + assert_eq!(result.stdout, at.read("lists_multiple_fields.expected")); +} + +#[test] +fn test_tail() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-d", ":", "--complement", "-f", "1", INPUT]).run(); + assert_eq!(result.stdout, at.read("lists_tail.expected")); +} + +#[test] +fn test_change_delimiter() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-d", ":", "--complement", "--output-delimiter=#", "-f", "1", INPUT]) + .run(); + assert_eq!(result.stdout, at.read("lists_change_delimiter.expected")); +} diff --git a/tests/dirname.rs b/tests/dirname.rs new file mode 100644 index 000000000..4c679514d --- /dev/null +++ b/tests/dirname.rs @@ -0,0 +1,25 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "dirname"; + + +#[test] +fn test_path_with_trailing_slashes() { + let (_, mut ucmd) = testing(UTIL_NAME); + let dir = "/root/alpha/beta/gamma/delta/epsilon/omega//"; + let out = ucmd.arg(dir).run().stdout; + + assert_eq!(out.trim_right(), "/root/alpha/beta/gamma/delta/epsilon"); +} + +#[test] +fn test_path_without_trailing_slashes() { + let (_, mut ucmd) = testing(UTIL_NAME); + let dir = "/root/alpha/beta/gamma/delta/epsilon/omega"; + let out = ucmd.arg(dir).run().stdout; + + assert_eq!(out.trim_right(), "/root/alpha/beta/gamma/delta/epsilon"); +} diff --git a/tests/echo.rs b/tests/echo.rs new file mode 100644 index 000000000..efc36cf8d --- /dev/null +++ b/tests/echo.rs @@ -0,0 +1,39 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "echo"; + +#[test] +fn test_default() { + let (_, mut ucmd) = testing(UTIL_NAME); + assert_eq!(ucmd.run().stdout, "\n"); +} + +#[test] +fn test_no_trailing_newline() { + let (_, mut ucmd) = testing(UTIL_NAME); + ucmd.arg("-n") + .arg("hello_world"); + + assert_eq!(ucmd.run().stdout, "hello_world"); +} + +#[test] +fn test_enable_escapes() { + let (_, mut ucmd) = testing(UTIL_NAME); + ucmd.arg("-e") + .arg("\\\\\\t\\r"); + + assert_eq!(ucmd.run().stdout, "\\\t\r\n"); +} + +#[test] +fn test_disable_escapes() { + let (_, mut ucmd) = testing(UTIL_NAME); + ucmd.arg("-E") + .arg("\\b\\c\\e"); + + assert_eq!(ucmd.run().stdout, "\\b\\c\\e\n"); +} diff --git a/tests/env.rs b/tests/env.rs new file mode 100644 index 000000000..7630a1fae --- /dev/null +++ b/tests/env.rs @@ -0,0 +1,72 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "env"; + +#[test] +fn test_single_name_value_pair() { + let (_, mut ucmd) = testing(UTIL_NAME); + let out = ucmd.arg("FOO=bar").run().stdout; + + assert!(out.lines().any(|line| line == "FOO=bar")); +} + +#[test] +fn test_multiple_name_value_pairs() { + let (_, mut ucmd) = testing(UTIL_NAME); + let out = ucmd.arg("FOO=bar") + .arg("ABC=xyz") + .run() + .stdout; + + assert_eq!(out.lines().filter(|&line| line == "FOO=bar" || line == "ABC=xyz").count(), + 2); +} + +#[test] +fn test_ignore_environment() { + let ts = TestSet::new(UTIL_NAME); + + let out = ts.util_cmd() + .arg("-i") + .run() + .stdout; + + assert_eq!(out, ""); + + let out = ts.util_cmd() + .arg("-") + .run() + .stdout; + + assert_eq!(out, ""); +} + +#[test] +fn test_null_delimiter() { + let (_, mut ucmd) = testing(UTIL_NAME); + let out = ucmd.arg("-i") + .arg("--null") + .arg("FOO=bar") + .arg("ABC=xyz") + .run() + .stdout; + + assert_eq!(out, "FOO=bar\0ABC=xyz\0"); +} + +#[test] +fn test_unset_variable() { + // This test depends on the HOME variable being pre-defined by the + // default shell + let out = TestSet::new(UTIL_NAME) + .util_cmd_keepenv() + .arg("-u") + .arg("HOME") + .run() + .stdout; + + assert_eq!(out.lines().any(|line| line.starts_with("HOME=")), false); +} diff --git a/tests/factor.rs b/tests/factor.rs new file mode 100644 index 000000000..1da6a41cd --- /dev/null +++ b/tests/factor.rs @@ -0,0 +1,1057 @@ +// +// This file is part of the uutils coreutils package. +// +// (c) kwantam +// +// For the full copyright and license information, please view the LICENSE file +// that was distributed with this source code. +// + +#[macro_use] +mod common; + +use common::util::*; + +extern crate libc; +extern crate rand; + +use rand::{weak_rng, Rng}; +use rand::distributions::{IndependentSample, Range}; +use sieve::Sieve; + +#[path="../src/factor/sieve.rs"] +mod sieve; + +const NUM_PRIMES: usize = 10000; +const LOG_PRIMES: f64 = 14.0; // ceil(log2(NUM_PRIMES)) + +const NUM_TESTS: usize = 100; + +static UTIL_NAME: &'static str = "factor"; + +#[test] +fn test_random() { + let primes = Sieve::primes().take(NUM_PRIMES).collect::>(); + + let mut rng = weak_rng(); + let mut rand_gt = move |min: u64| { + let mut product = 1u64; + let mut factors = Vec::new(); + while product < min { + // log distribution---higher probability for lower numbers + let factor; + loop { + let next = rng.gen_range(0f64, LOG_PRIMES).exp2().floor() as usize; + if next < NUM_PRIMES { + factor = primes[next]; + break; + } + } + let factor = factor; + + match product.checked_mul(factor) { + Some(p) => { + product = p; + factors.push(factor); + } + None => break, + }; + } + + factors.sort(); + (product, factors) + }; + + // build an input and expected output string from factor + let mut instring = String::new(); + let mut outstring = String::new(); + for _ in 0..NUM_TESTS { + let (product, factors) = rand_gt(1 << 63); + instring.push_str(&(format!("{} ", product))[..]); + + outstring.push_str(&(format!("{}:", product))[..]); + for factor in factors { + outstring.push_str(&(format!(" {}", factor))[..]); + } + outstring.push_str("\n"); + } + + run(instring.as_bytes(), outstring.as_bytes()); +} + +#[test] +fn test_random_big() { + let mut rng = weak_rng(); + let bitrange_1 = Range::new(14usize, 51); + let mut rand_64 = move || { + // first, choose a random number of bits for the first factor + let f_bit_1 = bitrange_1.ind_sample(&mut rng); + // how many more bits do we need? + let rem = 64 - f_bit_1; + + // we will have a number of additional factors equal to nfacts + 1 + // where nfacts is in [0, floor(rem/14) ) NOTE half-open interval + // Each prime factor is at least 14 bits, hence floor(rem/14) + let nfacts = Range::new(0usize, rem / 14).ind_sample(&mut rng); + // we have to distribute extrabits among the (nfacts + 1) values + let extrabits = rem - (nfacts + 1) * 14; + // (remember, a Range is a half-open interval) + let extrarange = Range::new(0usize, extrabits + 1); + + // to generate an even split of this range, generate n-1 random elements + // in the range, add the desired total value to the end, sort this list, + // and then compute the sequential differences. + let mut f_bits = Vec::new(); + for _ in 0..nfacts { + f_bits.push(extrarange.ind_sample(&mut rng)); + } + f_bits.push(extrabits); + f_bits.sort(); + + // compute sequential differences here. We leave off the +14 bits + // so we can just index PRIMES_BY_BITS + let mut f_bits = f_bits.iter() + .scan(0, |st, &x| { + let ret = x - *st; // + 14 would give actual number of bits + *st = x; + Some(ret) + }) + .collect::>(); + // finally, add f_bit_1 in there + f_bits.push(f_bit_1 - 14); // index of f_bit_1 in PRIMES_BY_BITS + let f_bits = f_bits; + + let mut nbits = 0; + let mut product = 1u64; + let mut factors = Vec::new(); + for bit in f_bits { + assert!(bit < 37); + nbits += 14 + bit; + let elm = Range::new(0, PRIMES_BY_BITS[bit].len()).ind_sample(&mut rng); + let factor = PRIMES_BY_BITS[bit][elm]; + factors.push(factor); + product *= factor; + } + assert_eq!(nbits, 64); + + factors.sort(); + (product, factors) + }; + + let mut instring = String::new(); + let mut outstring = String::new(); + for _ in 0..NUM_TESTS { + let (product, factors) = rand_64(); + instring.push_str(&(format!("{} ", product))[..]); + + outstring.push_str(&(format!("{}:", product))[..]); + for factor in factors { + outstring.push_str(&(format!(" {}", factor))[..]); + } + outstring.push_str("\n"); + } + + run(instring.as_bytes(), outstring.as_bytes()); +} + +#[test] +fn test_big_primes() { + let mut instring = String::new(); + let mut outstring = String::new(); + for prime in PRIMES64 { + instring.push_str(&(format!("{} ", prime))[..]); + outstring.push_str(&(format!("{0}: {0}\n", prime))[..]); + } + + run(instring.as_bytes(), outstring.as_bytes()); +} + +fn run(instring: &[u8], outstring: &[u8]) { + let (_, mut ucmd) = testing(UTIL_NAME); + // now run factor + let out = ucmd.run_piped_stdin(instring).stdout; + assert_eq!(out, String::from_utf8(outstring.to_owned()).unwrap()); +} + +const PRIMES_BY_BITS: &'static [&'static [u64]] = &[PRIMES14, PRIMES15, PRIMES16, PRIMES17, + PRIMES18, PRIMES19, PRIMES20, PRIMES21, + PRIMES22, PRIMES23, PRIMES24, PRIMES25, + PRIMES26, PRIMES27, PRIMES28, PRIMES29, + PRIMES30, PRIMES31, PRIMES32, PRIMES33, + PRIMES34, PRIMES35, PRIMES36, PRIMES37, + PRIMES38, PRIMES39, PRIMES40, PRIMES41, + PRIMES42, PRIMES43, PRIMES44, PRIMES45, + PRIMES46, PRIMES47, PRIMES48, PRIMES49, + PRIMES50]; + +const PRIMES64: &'static [u64] = &[18446744073709551557, + 18446744073709551533, + 18446744073709551521, + 18446744073709551437, + 18446744073709551427, + 18446744073709551359, + 18446744073709551337, + 18446744073709551293, + 18446744073709551263, + 18446744073709551253, + 18446744073709551191, + 18446744073709551163, + 18446744073709551113, + 18446744073709550873, + 18446744073709550791, + 18446744073709550773, + 18446744073709550771, + 18446744073709550719, + 18446744073709550717, + 18446744073709550681, + 18446744073709550671, + 18446744073709550593, + 18446744073709550591, + 18446744073709550539, + 18446744073709550537, + 18446744073709550381, + 18446744073709550341, + 18446744073709550293, + 18446744073709550237, + 18446744073709550147, + 18446744073709550141, + 18446744073709550129, + 18446744073709550111, + 18446744073709550099, + 18446744073709550047, + 18446744073709550033, + 18446744073709550009, + 18446744073709549951, + 18446744073709549861, + 18446744073709549817, + 18446744073709549811, + 18446744073709549777, + 18446744073709549757, + 18446744073709549733, + 18446744073709549667, + 18446744073709549621, + 18446744073709549613, + 18446744073709549583, + 18446744073709549571]; + +const PRIMES14: &'static [u64] = &[16381, 16369, 16363, 16361, 16349, 16339, 16333, 16319, 16301, + 16273, 16267, 16253, 16249, 16231, 16229, 16223, 16217, 16193, + 16189, 16187, 16183, 16141, 16139, 16127, 16111, 16103, 16097, + 16091, 16087, 16073, 16069, 16067, 16063, 16061, 16057, 16033, + 16007, 16001, 15991, 15973, 15971, 15959, 15937, 15923, 15919, + 15913, 15907, 15901, 15889, 15887, 15881, 15877, 15859, 15823, + 15817, 15809, 15803, 15797, 15791, 15787, 15773, 15767, 15761, + 15749, 15739, 15737, 15733, 15731, 15727, 15683, 15679, 15671, + 15667, 15661, 15649, 15647, 15643, 15641, 15629, 15619, 15607, + 15601, 15583, 15581, 15569, 15559, 15551, 15541, 15527, 15511, + 15497, 15493, 15473, 15467, 15461, 15451, 15443, 15439, 15427, + 15413, 15401, 15391, 15383, 15377, 15373]; + +const PRIMES15: &'static [u64] = &[32749, 32719, 32717, 32713, 32707, 32693, 32687, 32653, 32647, + 32633, 32621, 32611, 32609, 32603, 32587, 32579, 32573, 32569, + 32563, 32561, 32537, 32533, 32531, 32507, 32503, 32497, 32491, + 32479, 32467, 32443, 32441, 32429, 32423, 32413, 32411, 32401, + 32381, 32377, 32371, 32369, 32363, 32359, 32353, 32341, 32327, + 32323, 32321, 32309, 32303, 32299, 32297, 32261, 32257, 32251, + 32237, 32233, 32213, 32203, 32191, 32189, 32183, 32173, 32159, + 32143, 32141, 32119, 32117, 32099, 32089, 32083, 32077, 32069, + 32063, 32059, 32057, 32051, 32029, 32027, 32009, 32003, 31991, + 31981, 31973, 31963, 31957, 31907, 31891, 31883, 31873, 31859, + 31849, 31847, 31817, 31799, 31793, 31771, 31769, 31751]; + +const PRIMES16: &'static [u64] = &[65521, 65519, 65497, 65479, 65449, 65447, 65437, 65423, 65419, + 65413, 65407, 65393, 65381, 65371, 65357, 65353, 65327, 65323, + 65309, 65293, 65287, 65269, 65267, 65257, 65239, 65213, 65203, + 65183, 65179, 65173, 65171, 65167, 65147, 65141, 65129, 65123, + 65119, 65111, 65101, 65099, 65089, 65071, 65063, 65053, 65033, + 65029, 65027, 65011, 65003, 64997, 64969, 64951, 64937, 64927, + 64921, 64919, 64901, 64891, 64879, 64877, 64871, 64853, 64849, + 64817, 64811, 64793, 64783, 64781, 64763, 64747, 64717, 64709, + 64693, 64679, 64667, 64663, 64661, 64633, 64627, 64621, 64613, + 64609, 64601, 64591, 64579, 64577, 64567, 64553]; + +const PRIMES17: &'static [u64] = &[131071, 131063, 131059, 131041, 131023, 131011, 131009, 130987, + 130981, 130973, 130969, 130957, 130927, 130873, 130859, 130843, + 130841, 130829, 130817, 130811, 130807, 130787, 130783, 130769, + 130729, 130699, 130693, 130687, 130681, 130657, 130651, 130649, + 130643, 130639, 130633, 130631, 130621, 130619, 130589, 130579, + 130553, 130547, 130531, 130523, 130517, 130513, 130489, 130483, + 130477, 130469, 130457, 130447, 130439, 130423, 130411, 130409, + 130399, 130379, 130369, 130367, 130363, 130349, 130343, 130337, + 130307, 130303, 130279, 130267, 130261, 130259, 130253, 130241, + 130223, 130211, 130201, 130199, 130183, 130171, 130147, 130127, + 130121, 130099, 130087, 130079, 130073, 130069, 130057, 130051]; + +const PRIMES18: &'static [u64] = &[262139, 262133, 262127, 262121, 262111, 262109, 262103, 262079, + 262069, 262051, 262049, 262027, 262007, 261983, 261977, 261973, + 261971, 261959, 261917, 261887, 261881, 261847, 261823, 261799, + 261791, 261787, 261773, 261761, 261757, 261739, 261721, 261713, + 261707, 261697, 261673, 261643, 261641, 261637, 261631, 261619, + 261601, 261593, 261587, 261581, 261577, 261563, 261557, 261529, + 261523, 261509, 261467, 261463, 261451, 261439, 261433, 261431, + 261427, 261407, 261389, 261379, 261353, 261347, 261337, 261329, + 261323, 261301, 261281, 261271, 261251, 261241, 261229, 261223, + 261169, 261167, 261127]; + +const PRIMES19: &'static [u64] = &[524287, 524269, 524261, 524257, 524243, 524231, 524221, 524219, + 524203, 524201, 524197, 524189, 524171, 524149, 524123, 524119, + 524113, 524099, 524087, 524081, 524071, 524063, 524057, 524053, + 524047, 523997, 523987, 523969, 523949, 523937, 523927, 523907, + 523903, 523877, 523867, 523847, 523829, 523801, 523793, 523777, + 523771, 523763, 523759, 523741, 523729, 523717, 523681, 523673, + 523669, 523667, 523657, 523639, 523637, 523631, 523603, 523597, + 523577, 523573, 523571, 523553, 523543, 523541, 523519, 523511, + 523493, 523489, 523487, 523463, 523459, 523433, 523427, 523417, + 523403, 523387, 523357, 523351, 523349, 523333, 523307, 523297]; + +const PRIMES20: &'static [u64] = &[1048573, 1048571, 1048559, 1048549, 1048517, 1048507, 1048447, + 1048433, 1048423, 1048391, 1048387, 1048367, 1048361, 1048357, + 1048343, 1048309, 1048291, 1048273, 1048261, 1048219, 1048217, + 1048213, 1048193, 1048189, 1048139, 1048129, 1048127, 1048123, + 1048063, 1048051, 1048049, 1048043, 1048027, 1048013, 1048009, + 1048007, 1047997, 1047989, 1047979, 1047971, 1047961, 1047941, + 1047929, 1047923, 1047887, 1047883, 1047881, 1047859, 1047841, + 1047833, 1047821, 1047779, 1047773, 1047763, 1047751, 1047737, + 1047721, 1047713, 1047703, 1047701, 1047691, 1047689, 1047671, + 1047667, 1047653, 1047649, 1047647, 1047589, 1047587, 1047559]; + +const PRIMES21: &'static [u64] = &[2097143, 2097133, 2097131, 2097097, 2097091, 2097083, 2097047, + 2097041, 2097031, 2097023, 2097013, 2096993, 2096987, 2096971, + 2096959, 2096957, 2096947, 2096923, 2096911, 2096909, 2096893, + 2096881, 2096873, 2096867, 2096851, 2096837, 2096807, 2096791, + 2096789, 2096777, 2096761, 2096741, 2096737, 2096713, 2096693, + 2096687, 2096681, 2096639, 2096629, 2096621, 2096599, 2096597, + 2096569, 2096539, 2096533, 2096483, 2096449, 2096431, 2096429, + 2096411, 2096407, 2096401, 2096399, 2096377, 2096357, 2096291, + 2096273, 2096261, 2096233, 2096231, 2096221, 2096209, 2096191, + 2096183, 2096147]; + +const PRIMES22: &'static [u64] = &[4194301, 4194287, 4194277, 4194271, 4194247, 4194217, 4194199, + 4194191, 4194187, 4194181, 4194173, 4194167, 4194143, 4194137, + 4194131, 4194107, 4194103, 4194023, 4194011, 4194007, 4193977, + 4193971, 4193963, 4193957, 4193939, 4193929, 4193909, 4193869, + 4193807, 4193803, 4193801, 4193789, 4193759, 4193753, 4193743, + 4193701, 4193663, 4193633, 4193573, 4193569, 4193551, 4193549, + 4193531, 4193513, 4193507, 4193459, 4193447, 4193443, 4193417, + 4193411, 4193393, 4193389, 4193381, 4193377, 4193369, 4193359, + 4193353, 4193327, 4193309, 4193303, 4193297]; + +const PRIMES23: &'static [u64] = &[8388593, 8388587, 8388581, 8388571, 8388547, 8388539, 8388473, + 8388461, 8388451, 8388449, 8388439, 8388427, 8388421, 8388409, + 8388377, 8388371, 8388319, 8388301, 8388287, 8388283, 8388277, + 8388239, 8388209, 8388187, 8388113, 8388109, 8388091, 8388071, + 8388059, 8388019, 8388013, 8387999, 8387993, 8387959, 8387957, + 8387947, 8387933, 8387921, 8387917, 8387891, 8387879, 8387867, + 8387861, 8387857, 8387839, 8387831, 8387809, 8387807, 8387741, + 8387737, 8387723, 8387707, 8387671, 8387611, 8387609, 8387591]; + +const PRIMES24: &'static [u64] = &[16777213, 16777199, 16777183, 16777153, 16777141, 16777139, + 16777127, 16777121, 16777099, 16777049, 16777027, 16776989, + 16776973, 16776971, 16776967, 16776961, 16776941, 16776937, + 16776931, 16776919, 16776901, 16776899, 16776869, 16776857, + 16776839, 16776833, 16776817, 16776763, 16776731, 16776719, + 16776713, 16776691, 16776689, 16776679, 16776659, 16776631, + 16776623, 16776619, 16776607, 16776593, 16776581, 16776547, + 16776521, 16776491, 16776481, 16776469, 16776451, 16776401, + 16776391, 16776379, 16776371, 16776367, 16776343, 16776337, + 16776317, 16776313, 16776289, 16776217, 16776211]; + +const PRIMES25: &'static [u64] = &[33554393, 33554383, 33554371, 33554347, 33554341, 33554317, + 33554291, 33554273, 33554267, 33554249, 33554239, 33554221, + 33554201, 33554167, 33554159, 33554137, 33554123, 33554093, + 33554083, 33554077, 33554051, 33554021, 33554011, 33554009, + 33553999, 33553991, 33553969, 33553967, 33553909, 33553901, + 33553879, 33553837, 33553799, 33553787, 33553771, 33553769, + 33553759, 33553747, 33553739, 33553727, 33553697, 33553693, + 33553679, 33553661, 33553657, 33553651, 33553649, 33553633, + 33553613, 33553607, 33553577, 33553549, 33553547, 33553537, + 33553519, 33553517, 33553511, 33553489, 33553463, 33553451, + 33553417]; + +const PRIMES26: &'static [u64] = &[67108859, 67108837, 67108819, 67108777, 67108763, 67108757, + 67108753, 67108747, 67108739, 67108729, 67108721, 67108709, + 67108693, 67108669, 67108667, 67108661, 67108649, 67108633, + 67108597, 67108579, 67108529, 67108511, 67108507, 67108493, + 67108471, 67108463, 67108453, 67108439, 67108387, 67108373, + 67108369, 67108351, 67108331, 67108313, 67108303, 67108289, + 67108271, 67108219, 67108207, 67108201, 67108199, 67108187, + 67108183, 67108177, 67108127, 67108109, 67108081, 67108049, + 67108039, 67108037, 67108033, 67108009, 67108007, 67108003, + 67107983, 67107977, 67107967, 67107941, 67107919, 67107913, + 67107883, 67107881, 67107871, 67107863]; + +const PRIMES27: &'static [u64] = &[134217689, 134217649, 134217617, 134217613, 134217593, + 134217541, 134217529, 134217509, 134217497, 134217493, + 134217487, 134217467, 134217439, 134217437, 134217409, + 134217403, 134217401, 134217367, 134217361, 134217353, + 134217323, 134217301, 134217277, 134217257, 134217247, + 134217221, 134217199, 134217173, 134217163, 134217157, + 134217131, 134217103, 134217089, 134217079, 134217049, + 134217047, 134217043, 134217001, 134216987, 134216947, + 134216939, 134216933, 134216911, 134216899, 134216881, + 134216869, 134216867, 134216861, 134216837, 134216827, + 134216807, 134216801, 134216791, 134216783, 134216777, + 134216759, 134216737, 134216729]; + +const PRIMES28: &'static [u64] = &[268435399, 268435367, 268435361, 268435337, 268435331, + 268435313, 268435291, 268435273, 268435243, 268435183, + 268435171, 268435157, 268435147, 268435133, 268435129, + 268435121, 268435109, 268435091, 268435067, 268435043, + 268435039, 268435033, 268435019, 268435009, 268435007, + 268434997, 268434979, 268434977, 268434961, 268434949, + 268434941, 268434937, 268434857, 268434841, 268434827, + 268434821, 268434787, 268434781, 268434779, 268434773, + 268434731, 268434721, 268434713, 268434707, 268434703, + 268434697, 268434659, 268434623, 268434619, 268434581, + 268434577, 268434563, 268434557, 268434547, 268434511, + 268434499, 268434479, 268434461]; + +const PRIMES29: &'static [u64] = &[536870909, 536870879, 536870869, 536870849, 536870839, + 536870837, 536870819, 536870813, 536870791, 536870779, + 536870767, 536870743, 536870729, 536870723, 536870717, + 536870701, 536870683, 536870657, 536870641, 536870627, + 536870611, 536870603, 536870599, 536870573, 536870569, + 536870563, 536870561, 536870513, 536870501, 536870497, + 536870473, 536870401, 536870363, 536870317, 536870303, + 536870297, 536870273, 536870267, 536870239, 536870233, + 536870219, 536870171, 536870167, 536870153, 536870123, + 536870063, 536870057, 536870041, 536870027, 536869999, + 536869951, 536869943, 536869937, 536869919, 536869901, + 536869891]; + +const PRIMES30: &'static [u64] = &[1073741789, 1073741783, 1073741741, 1073741723, 1073741719, + 1073741717, 1073741689, 1073741671, 1073741663, 1073741651, + 1073741621, 1073741567, 1073741561, 1073741527, 1073741503, + 1073741477, 1073741467, 1073741441, 1073741419, 1073741399, + 1073741387, 1073741381, 1073741371, 1073741329, 1073741311, + 1073741309, 1073741287, 1073741237, 1073741213, 1073741197, + 1073741189, 1073741173, 1073741101, 1073741077, 1073741047, + 1073740963, 1073740951, 1073740933, 1073740909, 1073740879, + 1073740853, 1073740847, 1073740819, 1073740807]; + +const PRIMES31: &'static [u64] = &[2147483647, 2147483629, 2147483587, 2147483579, 2147483563, + 2147483549, 2147483543, 2147483497, 2147483489, 2147483477, + 2147483423, 2147483399, 2147483353, 2147483323, 2147483269, + 2147483249, 2147483237, 2147483179, 2147483171, 2147483137, + 2147483123, 2147483077, 2147483069, 2147483059, 2147483053, + 2147483033, 2147483029, 2147482951, 2147482949, 2147482943, + 2147482937, 2147482921, 2147482877, 2147482873, 2147482867, + 2147482859, 2147482819, 2147482817, 2147482811, 2147482801, + 2147482763, 2147482739, 2147482697, 2147482693, 2147482681, + 2147482663, 2147482661]; + +const PRIMES32: &'static [u64] = &[4294967291, 4294967279, 4294967231, 4294967197, 4294967189, + 4294967161, 4294967143, 4294967111, 4294967087, 4294967029, + 4294966997, 4294966981, 4294966943, 4294966927, 4294966909, + 4294966877, 4294966829, 4294966813, 4294966769, 4294966667, + 4294966661, 4294966657, 4294966651, 4294966639, 4294966619, + 4294966591, 4294966583, 4294966553, 4294966477, 4294966447, + 4294966441, 4294966427, 4294966373, 4294966367, 4294966337, + 4294966297]; + +const PRIMES33: &'static [u64] = &[8589934583, 8589934567, 8589934543, 8589934513, 8589934487, + 8589934307, 8589934291, 8589934289, 8589934271, 8589934237, + 8589934211, 8589934207, 8589934201, 8589934187, 8589934151, + 8589934141, 8589934139, 8589934117, 8589934103, 8589934099, + 8589934091, 8589934069, 8589934049, 8589934027, 8589934007, + 8589933973, 8589933971, 8589933967, 8589933931, 8589933917, + 8589933907, 8589933853, 8589933827, 8589933823, 8589933787, + 8589933773, 8589933733, 8589933731, 8589933721, 8589933683, + 8589933647, 8589933641, 8589933637, 8589933631, 8589933629, + 8589933619, 8589933601, 8589933581]; + +const PRIMES34: &'static [u64] = &[17179869143, + 17179869107, + 17179869071, + 17179869053, + 17179869041, + 17179869019, + 17179868999, + 17179868977, + 17179868957, + 17179868903, + 17179868899, + 17179868887, + 17179868879, + 17179868873, + 17179868869, + 17179868861, + 17179868843, + 17179868833, + 17179868809, + 17179868807, + 17179868777, + 17179868759, + 17179868729, + 17179868711, + 17179868683, + 17179868681, + 17179868597, + 17179868549, + 17179868543, + 17179868521, + 17179868513, + 17179868479, + 17179868443, + 17179868437, + 17179868429, + 17179868383, + 17179868369, + 17179868357, + 17179868353, + 17179868351, + 17179868333, + 17179868317, + 17179868309, + 17179868297, + 17179868287, + 17179868249, + 17179868243, + 17179868183]; + +const PRIMES35: &'static [u64] = &[34359738337, + 34359738319, + 34359738307, + 34359738299, + 34359738289, + 34359738247, + 34359738227, + 34359738121, + 34359738059, + 34359738043, + 34359738011, + 34359737917, + 34359737869, + 34359737849, + 34359737837, + 34359737821, + 34359737813, + 34359737791, + 34359737777, + 34359737771, + 34359737717, + 34359737591, + 34359737567, + 34359737549, + 34359737519, + 34359737497, + 34359737479, + 34359737407, + 34359737393, + 34359737371]; + +const PRIMES36: &'static [u64] = &[68719476731, + 68719476719, + 68719476713, + 68719476671, + 68719476619, + 68719476599, + 68719476577, + 68719476563, + 68719476547, + 68719476503, + 68719476493, + 68719476479, + 68719476433, + 68719476407, + 68719476391, + 68719476389, + 68719476377, + 68719476361, + 68719476323, + 68719476307, + 68719476281, + 68719476271, + 68719476257, + 68719476247, + 68719476209, + 68719476197, + 68719476181, + 68719476169, + 68719476157, + 68719476149, + 68719476109, + 68719476053, + 68719476047, + 68719476019, + 68719475977, + 68719475947, + 68719475933, + 68719475911, + 68719475893, + 68719475879, + 68719475837, + 68719475827, + 68719475809, + 68719475791, + 68719475779, + 68719475771, + 68719475767, + 68719475731, + 68719475729]; + +const PRIMES37: &'static [u64] = &[137438953447, + 137438953441, + 137438953427, + 137438953403, + 137438953349, + 137438953331, + 137438953273, + 137438953271, + 137438953121, + 137438953097, + 137438953037, + 137438953009, + 137438952953, + 137438952901, + 137438952887, + 137438952869, + 137438952853, + 137438952731, + 137438952683, + 137438952611, + 137438952529, + 137438952503, + 137438952491]; + +const PRIMES38: &'static [u64] = &[274877906899, + 274877906857, + 274877906837, + 274877906813, + 274877906791, + 274877906759, + 274877906753, + 274877906717, + 274877906713, + 274877906687, + 274877906647, + 274877906629, + 274877906627, + 274877906573, + 274877906543, + 274877906491, + 274877906477, + 274877906473, + 274877906431, + 274877906419, + 274877906341, + 274877906333, + 274877906327, + 274877906321, + 274877906309, + 274877906267, + 274877906243, + 274877906213, + 274877906209, + 274877906203, + 274877906179, + 274877906167, + 274877906119, + 274877906063, + 274877906053, + 274877906021, + 274877905931]; + +const PRIMES39: &'static [u64] = &[549755813881, + 549755813869, + 549755813821, + 549755813797, + 549755813753, + 549755813723, + 549755813669, + 549755813657, + 549755813647, + 549755813587, + 549755813561, + 549755813513, + 549755813507, + 549755813461, + 549755813417, + 549755813401, + 549755813371, + 549755813359, + 549755813357, + 549755813351, + 549755813339, + 549755813317, + 549755813311, + 549755813281, + 549755813239, + 549755813231, + 549755813213, + 549755813207, + 549755813197, + 549755813183, + 549755813161, + 549755813149, + 549755813147, + 549755813143, + 549755813141, + 549755813059, + 549755813027, + 549755813003, + 549755812951, + 549755812937, + 549755812933, + 549755812889, + 549755812867]; + +const PRIMES40: &'static [u64] = &[1099511627689, + 1099511627609, + 1099511627581, + 1099511627573, + 1099511627563, + 1099511627491, + 1099511627483, + 1099511627477, + 1099511627387, + 1099511627339, + 1099511627321, + 1099511627309, + 1099511627297, + 1099511627293, + 1099511627261, + 1099511627213, + 1099511627191, + 1099511627177, + 1099511627173, + 1099511627143, + 1099511627089, + 1099511626987, + 1099511626949, + 1099511626937, + 1099511626793, + 1099511626781, + 1099511626771]; + +const PRIMES41: &'static [u64] = &[2199023255531, + 2199023255521, + 2199023255497, + 2199023255489, + 2199023255479, + 2199023255477, + 2199023255461, + 2199023255441, + 2199023255419, + 2199023255413, + 2199023255357, + 2199023255327, + 2199023255291, + 2199023255279, + 2199023255267, + 2199023255243, + 2199023255203, + 2199023255171, + 2199023255137, + 2199023255101, + 2199023255087, + 2199023255081, + 2199023255069, + 2199023255027, + 2199023255021, + 2199023254979, + 2199023254933, + 2199023254913, + 2199023254907, + 2199023254903, + 2199023254843, + 2199023254787, + 2199023254699, + 2199023254693, + 2199023254657, + 2199023254567]; + +const PRIMES42: &'static [u64] = &[4398046511093, + 4398046511087, + 4398046511071, + 4398046511051, + 4398046511039, + 4398046510961, + 4398046510943, + 4398046510939, + 4398046510889, + 4398046510877, + 4398046510829, + 4398046510787, + 4398046510771, + 4398046510751, + 4398046510733, + 4398046510721, + 4398046510643, + 4398046510639, + 4398046510597, + 4398046510577, + 4398046510547, + 4398046510531, + 4398046510463, + 4398046510397, + 4398046510391, + 4398046510379, + 4398046510357, + 4398046510331, + 4398046510327, + 4398046510313, + 4398046510283, + 4398046510279, + 4398046510217, + 4398046510141, + 4398046510133, + 4398046510103, + 4398046510093]; + +const PRIMES43: &'static [u64] = &[8796093022151, + 8796093022141, + 8796093022091, + 8796093022033, + 8796093021953, + 8796093021941, + 8796093021917, + 8796093021899, + 8796093021889, + 8796093021839, + 8796093021803, + 8796093021791, + 8796093021769, + 8796093021763, + 8796093021743, + 8796093021671, + 8796093021607, + 8796093021587, + 8796093021533, + 8796093021523, + 8796093021517, + 8796093021493, + 8796093021467, + 8796093021461, + 8796093021449, + 8796093021409, + 8796093021407, + 8796093021371, + 8796093021347, + 8796093021337, + 8796093021281, + 8796093021269]; + +const PRIMES44: &'static [u64] = &[17592186044399, + 17592186044299, + 17592186044297, + 17592186044287, + 17592186044273, + 17592186044267, + 17592186044129, + 17592186044089, + 17592186044057, + 17592186044039, + 17592186043987, + 17592186043921, + 17592186043889, + 17592186043877, + 17592186043841, + 17592186043829, + 17592186043819, + 17592186043813, + 17592186043807, + 17592186043741, + 17592186043693, + 17592186043667, + 17592186043631, + 17592186043591, + 17592186043577, + 17592186043547, + 17592186043483, + 17592186043451, + 17592186043433, + 17592186043409]; + +const PRIMES45: &'static [u64] = &[35184372088777, + 35184372088763, + 35184372088751, + 35184372088739, + 35184372088711, + 35184372088699, + 35184372088693, + 35184372088673, + 35184372088639, + 35184372088603, + 35184372088571, + 35184372088517, + 35184372088493, + 35184372088471, + 35184372088403, + 35184372088391, + 35184372088379, + 35184372088363, + 35184372088321, + 35184372088319, + 35184372088279, + 35184372088259, + 35184372088249, + 35184372088241, + 35184372088223, + 35184372088183, + 35184372088097, + 35184372088081, + 35184372088079, + 35184372088051, + 35184372088043, + 35184372088039, + 35184372087937, + 35184372087929, + 35184372087923, + 35184372087881, + 35184372087877, + 35184372087869]; + +const PRIMES46: &'static [u64] = &[70368744177643, + 70368744177607, + 70368744177601, + 70368744177587, + 70368744177497, + 70368744177467, + 70368744177427, + 70368744177377, + 70368744177359, + 70368744177353, + 70368744177331, + 70368744177289, + 70368744177283, + 70368744177271, + 70368744177257, + 70368744177227, + 70368744177167, + 70368744177113, + 70368744177029, + 70368744176959, + 70368744176921, + 70368744176909, + 70368744176879, + 70368744176867, + 70368744176833, + 70368744176827, + 70368744176807, + 70368744176779, + 70368744176777, + 70368744176729, + 70368744176719, + 70368744176711]; + +const PRIMES47: &'static [u64] = &[140737488355213, + 140737488355201, + 140737488355181, + 140737488355049, + 140737488355031, + 140737488354989, + 140737488354893, + 140737488354787, + 140737488354709, + 140737488354679, + 140737488354613, + 140737488354557, + 140737488354511, + 140737488354431, + 140737488354413, + 140737488354409, + 140737488354373, + 140737488354347, + 140737488354329]; + +const PRIMES48: &'static [u64] = &[281474976710597, + 281474976710591, + 281474976710567, + 281474976710563, + 281474976710509, + 281474976710491, + 281474976710467, + 281474976710423, + 281474976710413, + 281474976710399, + 281474976710339, + 281474976710327, + 281474976710287, + 281474976710197, + 281474976710143, + 281474976710131, + 281474976710129, + 281474976710107, + 281474976710089, + 281474976710087, + 281474976710029, + 281474976709987, + 281474976709891, + 281474976709859, + 281474976709831, + 281474976709757, + 281474976709741, + 281474976709711, + 281474976709649, + 281474976709637]; + +const PRIMES49: &'static [u64] = &[562949953421231, + 562949953421201, + 562949953421189, + 562949953421173, + 562949953421131, + 562949953421111, + 562949953421099, + 562949953421047, + 562949953421029, + 562949953420973, + 562949953420871, + 562949953420867, + 562949953420837, + 562949953420793, + 562949953420747, + 562949953420741, + 562949953420733, + 562949953420727, + 562949953420609, + 562949953420571, + 562949953420559, + 562949953420553, + 562949953420523, + 562949953420507, + 562949953420457, + 562949953420403, + 562949953420373, + 562949953420369, + 562949953420343, + 562949953420303, + 562949953420297]; + +const PRIMES50: &'static [u64] = &[1125899906842597, + 1125899906842589, + 1125899906842573, + 1125899906842553, + 1125899906842511, + 1125899906842507, + 1125899906842493, + 1125899906842463, + 1125899906842429, + 1125899906842391, + 1125899906842357, + 1125899906842283, + 1125899906842273, + 1125899906842247, + 1125899906842201, + 1125899906842177, + 1125899906842079, + 1125899906842033, + 1125899906842021, + 1125899906842013, + 1125899906841973, + 1125899906841971, + 1125899906841959, + 1125899906841949, + 1125899906841943, + 1125899906841917, + 1125899906841901, + 1125899906841883, + 1125899906841859, + 1125899906841811, + 1125899906841803, + 1125899906841751, + 1125899906841713, + 1125899906841673, + 1125899906841653, + 1125899906841623, + 1125899906841613]; diff --git a/tests/false.rs b/tests/false.rs new file mode 100644 index 000000000..afa19b339 --- /dev/null +++ b/tests/false.rs @@ -0,0 +1,14 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "false"; + + +#[test] +fn test_exit_code() { + let (_, mut ucmd) = testing(UTIL_NAME); + let exit_status = ucmd.run().success; + assert_eq!(exit_status, false); +} diff --git a/test/fixtures/cat/256.txt b/tests/fixtures/cat/256.txt similarity index 100% rename from test/fixtures/cat/256.txt rename to tests/fixtures/cat/256.txt diff --git a/test/fixtures/cat/alpha.txt b/tests/fixtures/cat/alpha.txt similarity index 100% rename from test/fixtures/cat/alpha.txt rename to tests/fixtures/cat/alpha.txt diff --git a/test/fixtures/cksum/alice_in_wonderland.txt b/tests/fixtures/cksum/alice_in_wonderland.txt similarity index 100% rename from test/fixtures/cksum/alice_in_wonderland.txt rename to tests/fixtures/cksum/alice_in_wonderland.txt diff --git a/test/fixtures/cksum/lorem_ipsum.txt b/tests/fixtures/cksum/lorem_ipsum.txt similarity index 100% rename from test/fixtures/cksum/lorem_ipsum.txt rename to tests/fixtures/cksum/lorem_ipsum.txt diff --git a/test/fixtures/cksum/multiple_files.expected b/tests/fixtures/cksum/multiple_files.expected similarity index 100% rename from test/fixtures/cksum/multiple_files.expected rename to tests/fixtures/cksum/multiple_files.expected diff --git a/test/fixtures/cksum/single_file.expected b/tests/fixtures/cksum/single_file.expected similarity index 100% rename from test/fixtures/cksum/single_file.expected rename to tests/fixtures/cksum/single_file.expected diff --git a/test/fixtures/cksum/stdin.expected b/tests/fixtures/cksum/stdin.expected similarity index 100% rename from test/fixtures/cksum/stdin.expected rename to tests/fixtures/cksum/stdin.expected diff --git a/test/fixtures/cp/hello_world.txt b/tests/fixtures/cp/hello_world.txt similarity index 100% rename from test/fixtures/cp/hello_world.txt rename to tests/fixtures/cp/hello_world.txt diff --git a/test/fixtures/cut/lists.txt b/tests/fixtures/cut/lists.txt similarity index 100% rename from test/fixtures/cut/lists.txt rename to tests/fixtures/cut/lists.txt diff --git a/test/fixtures/cut/lists_change_delimiter.expected b/tests/fixtures/cut/lists_change_delimiter.expected similarity index 100% rename from test/fixtures/cut/lists_change_delimiter.expected rename to tests/fixtures/cut/lists_change_delimiter.expected diff --git a/test/fixtures/cut/lists_char_range.expected b/tests/fixtures/cut/lists_char_range.expected similarity index 100% rename from test/fixtures/cut/lists_char_range.expected rename to tests/fixtures/cut/lists_char_range.expected diff --git a/test/fixtures/cut/lists_column_to_end_of_line.expected b/tests/fixtures/cut/lists_column_to_end_of_line.expected similarity index 100% rename from test/fixtures/cut/lists_column_to_end_of_line.expected rename to tests/fixtures/cut/lists_column_to_end_of_line.expected diff --git a/test/fixtures/cut/lists_multiple_fields.expected b/tests/fixtures/cut/lists_multiple_fields.expected similarity index 100% rename from test/fixtures/cut/lists_multiple_fields.expected rename to tests/fixtures/cut/lists_multiple_fields.expected diff --git a/test/fixtures/cut/lists_prefix.expected b/tests/fixtures/cut/lists_prefix.expected similarity index 100% rename from test/fixtures/cut/lists_prefix.expected rename to tests/fixtures/cut/lists_prefix.expected diff --git a/test/fixtures/cut/lists_specific_field.expected b/tests/fixtures/cut/lists_specific_field.expected similarity index 100% rename from test/fixtures/cut/lists_specific_field.expected rename to tests/fixtures/cut/lists_specific_field.expected diff --git a/test/fixtures/cut/lists_tail.expected b/tests/fixtures/cut/lists_tail.expected similarity index 100% rename from test/fixtures/cut/lists_tail.expected rename to tests/fixtures/cut/lists_tail.expected diff --git a/test/fixtures/fold/lorem_ipsum.txt b/tests/fixtures/fold/lorem_ipsum.txt similarity index 100% rename from test/fixtures/fold/lorem_ipsum.txt rename to tests/fixtures/fold/lorem_ipsum.txt diff --git a/test/fixtures/fold/lorem_ipsum_40_column_hard.expected b/tests/fixtures/fold/lorem_ipsum_40_column_hard.expected similarity index 100% rename from test/fixtures/fold/lorem_ipsum_40_column_hard.expected rename to tests/fixtures/fold/lorem_ipsum_40_column_hard.expected diff --git a/test/fixtures/fold/lorem_ipsum_40_column_word.expected b/tests/fixtures/fold/lorem_ipsum_40_column_word.expected similarity index 100% rename from test/fixtures/fold/lorem_ipsum_40_column_word.expected rename to tests/fixtures/fold/lorem_ipsum_40_column_word.expected diff --git a/test/fixtures/fold/lorem_ipsum_80_column.expected b/tests/fixtures/fold/lorem_ipsum_80_column.expected similarity index 100% rename from test/fixtures/fold/lorem_ipsum_80_column.expected rename to tests/fixtures/fold/lorem_ipsum_80_column.expected diff --git a/test/fixtures/hashsum/input.txt b/tests/fixtures/hashsum/input.txt similarity index 100% rename from test/fixtures/hashsum/input.txt rename to tests/fixtures/hashsum/input.txt diff --git a/test/fixtures/hashsum/md5.expected b/tests/fixtures/hashsum/md5.expected similarity index 100% rename from test/fixtures/hashsum/md5.expected rename to tests/fixtures/hashsum/md5.expected diff --git a/test/fixtures/hashsum/sha1.expected b/tests/fixtures/hashsum/sha1.expected similarity index 100% rename from test/fixtures/hashsum/sha1.expected rename to tests/fixtures/hashsum/sha1.expected diff --git a/test/fixtures/hashsum/sha224.expected b/tests/fixtures/hashsum/sha224.expected similarity index 100% rename from test/fixtures/hashsum/sha224.expected rename to tests/fixtures/hashsum/sha224.expected diff --git a/test/fixtures/hashsum/sha256.expected b/tests/fixtures/hashsum/sha256.expected similarity index 100% rename from test/fixtures/hashsum/sha256.expected rename to tests/fixtures/hashsum/sha256.expected diff --git a/test/fixtures/hashsum/sha384.expected b/tests/fixtures/hashsum/sha384.expected similarity index 100% rename from test/fixtures/hashsum/sha384.expected rename to tests/fixtures/hashsum/sha384.expected diff --git a/test/fixtures/hashsum/sha512.expected b/tests/fixtures/hashsum/sha512.expected similarity index 100% rename from test/fixtures/hashsum/sha512.expected rename to tests/fixtures/hashsum/sha512.expected diff --git a/test/fixtures/head/lorem_ipsum.txt b/tests/fixtures/head/lorem_ipsum.txt similarity index 100% rename from test/fixtures/head/lorem_ipsum.txt rename to tests/fixtures/head/lorem_ipsum.txt diff --git a/test/fixtures/head/lorem_ipsum_1_line.expected b/tests/fixtures/head/lorem_ipsum_1_line.expected similarity index 100% rename from test/fixtures/head/lorem_ipsum_1_line.expected rename to tests/fixtures/head/lorem_ipsum_1_line.expected diff --git a/test/fixtures/head/lorem_ipsum_5_chars.expected b/tests/fixtures/head/lorem_ipsum_5_chars.expected similarity index 100% rename from test/fixtures/head/lorem_ipsum_5_chars.expected rename to tests/fixtures/head/lorem_ipsum_5_chars.expected diff --git a/test/fixtures/head/lorem_ipsum_default.expected b/tests/fixtures/head/lorem_ipsum_default.expected similarity index 100% rename from test/fixtures/head/lorem_ipsum_default.expected rename to tests/fixtures/head/lorem_ipsum_default.expected diff --git a/test/fixtures/head/lorem_ipsum_verbose.expected b/tests/fixtures/head/lorem_ipsum_verbose.expected similarity index 100% rename from test/fixtures/head/lorem_ipsum_verbose.expected rename to tests/fixtures/head/lorem_ipsum_verbose.expected diff --git a/test/fixtures/mv/hello_world.txt b/tests/fixtures/mv/hello_world.txt similarity index 100% rename from test/fixtures/mv/hello_world.txt rename to tests/fixtures/mv/hello_world.txt diff --git a/test/fixtures/nl/joinblanklines.txt b/tests/fixtures/nl/joinblanklines.txt similarity index 100% rename from test/fixtures/nl/joinblanklines.txt rename to tests/fixtures/nl/joinblanklines.txt diff --git a/test/fixtures/nl/section.txt b/tests/fixtures/nl/section.txt similarity index 100% rename from test/fixtures/nl/section.txt rename to tests/fixtures/nl/section.txt diff --git a/test/fixtures/nl/simple.txt b/tests/fixtures/nl/simple.txt similarity index 100% rename from test/fixtures/nl/simple.txt rename to tests/fixtures/nl/simple.txt diff --git a/test/fixtures/paste/html_colors.expected b/tests/fixtures/paste/html_colors.expected similarity index 100% rename from test/fixtures/paste/html_colors.expected rename to tests/fixtures/paste/html_colors.expected diff --git a/test/fixtures/paste/html_colors.txt b/tests/fixtures/paste/html_colors.txt similarity index 100% rename from test/fixtures/paste/html_colors.txt rename to tests/fixtures/paste/html_colors.txt diff --git a/test/fixtures/ptx/gnu_ext_disabled_ignore_and_only_file.expected b/tests/fixtures/ptx/gnu_ext_disabled_ignore_and_only_file.expected similarity index 100% rename from test/fixtures/ptx/gnu_ext_disabled_ignore_and_only_file.expected rename to tests/fixtures/ptx/gnu_ext_disabled_ignore_and_only_file.expected diff --git a/test/fixtures/ptx/gnu_ext_disabled_roff_auto_ref.expected b/tests/fixtures/ptx/gnu_ext_disabled_roff_auto_ref.expected similarity index 100% rename from test/fixtures/ptx/gnu_ext_disabled_roff_auto_ref.expected rename to tests/fixtures/ptx/gnu_ext_disabled_roff_auto_ref.expected diff --git a/test/fixtures/ptx/gnu_ext_disabled_roff_input_ref.expected b/tests/fixtures/ptx/gnu_ext_disabled_roff_input_ref.expected similarity index 100% rename from test/fixtures/ptx/gnu_ext_disabled_roff_input_ref.expected rename to tests/fixtures/ptx/gnu_ext_disabled_roff_input_ref.expected diff --git a/test/fixtures/ptx/gnu_ext_disabled_roff_no_ref.expected b/tests/fixtures/ptx/gnu_ext_disabled_roff_no_ref.expected similarity index 100% rename from test/fixtures/ptx/gnu_ext_disabled_roff_no_ref.expected rename to tests/fixtures/ptx/gnu_ext_disabled_roff_no_ref.expected diff --git a/test/fixtures/ptx/gnu_ext_disabled_tex_auto_ref.expected b/tests/fixtures/ptx/gnu_ext_disabled_tex_auto_ref.expected similarity index 100% rename from test/fixtures/ptx/gnu_ext_disabled_tex_auto_ref.expected rename to tests/fixtures/ptx/gnu_ext_disabled_tex_auto_ref.expected diff --git a/test/fixtures/ptx/gnu_ext_disabled_tex_input_ref.expected b/tests/fixtures/ptx/gnu_ext_disabled_tex_input_ref.expected similarity index 100% rename from test/fixtures/ptx/gnu_ext_disabled_tex_input_ref.expected rename to tests/fixtures/ptx/gnu_ext_disabled_tex_input_ref.expected diff --git a/test/fixtures/ptx/gnu_ext_disabled_tex_no_ref.expected b/tests/fixtures/ptx/gnu_ext_disabled_tex_no_ref.expected similarity index 100% rename from test/fixtures/ptx/gnu_ext_disabled_tex_no_ref.expected rename to tests/fixtures/ptx/gnu_ext_disabled_tex_no_ref.expected diff --git a/test/fixtures/ptx/ignore b/tests/fixtures/ptx/ignore similarity index 100% rename from test/fixtures/ptx/ignore rename to tests/fixtures/ptx/ignore diff --git a/test/fixtures/ptx/input b/tests/fixtures/ptx/input similarity index 100% rename from test/fixtures/ptx/input rename to tests/fixtures/ptx/input diff --git a/test/fixtures/ptx/only b/tests/fixtures/ptx/only similarity index 100% rename from test/fixtures/ptx/only rename to tests/fixtures/ptx/only diff --git a/test/fixtures/sort/human1.ans b/tests/fixtures/sort/human1.ans similarity index 100% rename from test/fixtures/sort/human1.ans rename to tests/fixtures/sort/human1.ans diff --git a/test/fixtures/sort/human1.txt b/tests/fixtures/sort/human1.txt similarity index 100% rename from test/fixtures/sort/human1.txt rename to tests/fixtures/sort/human1.txt diff --git a/test/fixtures/sort/numeric1.ans b/tests/fixtures/sort/numeric1.ans similarity index 100% rename from test/fixtures/sort/numeric1.ans rename to tests/fixtures/sort/numeric1.ans diff --git a/test/fixtures/sort/numeric1.txt b/tests/fixtures/sort/numeric1.txt similarity index 100% rename from test/fixtures/sort/numeric1.txt rename to tests/fixtures/sort/numeric1.txt diff --git a/test/fixtures/sort/numeric2.ans b/tests/fixtures/sort/numeric2.ans similarity index 100% rename from test/fixtures/sort/numeric2.ans rename to tests/fixtures/sort/numeric2.ans diff --git a/test/fixtures/sort/numeric2.txt b/tests/fixtures/sort/numeric2.txt similarity index 100% rename from test/fixtures/sort/numeric2.txt rename to tests/fixtures/sort/numeric2.txt diff --git a/test/fixtures/sort/numeric3.ans b/tests/fixtures/sort/numeric3.ans similarity index 100% rename from test/fixtures/sort/numeric3.ans rename to tests/fixtures/sort/numeric3.ans diff --git a/test/fixtures/sort/numeric3.txt b/tests/fixtures/sort/numeric3.txt similarity index 100% rename from test/fixtures/sort/numeric3.txt rename to tests/fixtures/sort/numeric3.txt diff --git a/test/fixtures/sort/numeric4.ans b/tests/fixtures/sort/numeric4.ans similarity index 100% rename from test/fixtures/sort/numeric4.ans rename to tests/fixtures/sort/numeric4.ans diff --git a/test/fixtures/sort/numeric4.txt b/tests/fixtures/sort/numeric4.txt similarity index 100% rename from test/fixtures/sort/numeric4.txt rename to tests/fixtures/sort/numeric4.txt diff --git a/test/fixtures/sort/numeric5.ans b/tests/fixtures/sort/numeric5.ans similarity index 100% rename from test/fixtures/sort/numeric5.ans rename to tests/fixtures/sort/numeric5.ans diff --git a/test/fixtures/sort/numeric5.txt b/tests/fixtures/sort/numeric5.txt similarity index 100% rename from test/fixtures/sort/numeric5.txt rename to tests/fixtures/sort/numeric5.txt diff --git a/test/fixtures/sort/numeric6.ans b/tests/fixtures/sort/numeric6.ans similarity index 100% rename from test/fixtures/sort/numeric6.ans rename to tests/fixtures/sort/numeric6.ans diff --git a/test/fixtures/sort/numeric6.txt b/tests/fixtures/sort/numeric6.txt similarity index 100% rename from test/fixtures/sort/numeric6.txt rename to tests/fixtures/sort/numeric6.txt diff --git a/test/fixtures/sum/alice_in_wonderland.txt b/tests/fixtures/sum/alice_in_wonderland.txt similarity index 100% rename from test/fixtures/sum/alice_in_wonderland.txt rename to tests/fixtures/sum/alice_in_wonderland.txt diff --git a/test/fixtures/sum/bsd_multiple_files.expected b/tests/fixtures/sum/bsd_multiple_files.expected similarity index 100% rename from test/fixtures/sum/bsd_multiple_files.expected rename to tests/fixtures/sum/bsd_multiple_files.expected diff --git a/test/fixtures/sum/bsd_single_file.expected b/tests/fixtures/sum/bsd_single_file.expected similarity index 100% rename from test/fixtures/sum/bsd_single_file.expected rename to tests/fixtures/sum/bsd_single_file.expected diff --git a/test/fixtures/sum/bsd_stdin.expected b/tests/fixtures/sum/bsd_stdin.expected similarity index 100% rename from test/fixtures/sum/bsd_stdin.expected rename to tests/fixtures/sum/bsd_stdin.expected diff --git a/test/fixtures/sum/lorem_ipsum.txt b/tests/fixtures/sum/lorem_ipsum.txt similarity index 100% rename from test/fixtures/sum/lorem_ipsum.txt rename to tests/fixtures/sum/lorem_ipsum.txt diff --git a/test/fixtures/sum/sysv_multiple_files.expected b/tests/fixtures/sum/sysv_multiple_files.expected similarity index 100% rename from test/fixtures/sum/sysv_multiple_files.expected rename to tests/fixtures/sum/sysv_multiple_files.expected diff --git a/test/fixtures/sum/sysv_single_file.expected b/tests/fixtures/sum/sysv_single_file.expected similarity index 100% rename from test/fixtures/sum/sysv_single_file.expected rename to tests/fixtures/sum/sysv_single_file.expected diff --git a/test/fixtures/sum/sysv_stdin.expected b/tests/fixtures/sum/sysv_stdin.expected similarity index 100% rename from test/fixtures/sum/sysv_stdin.expected rename to tests/fixtures/sum/sysv_stdin.expected diff --git a/test/fixtures/tac/delimited_primes.expected b/tests/fixtures/tac/delimited_primes.expected similarity index 100% rename from test/fixtures/tac/delimited_primes.expected rename to tests/fixtures/tac/delimited_primes.expected diff --git a/test/fixtures/tac/delimited_primes.txt b/tests/fixtures/tac/delimited_primes.txt similarity index 100% rename from test/fixtures/tac/delimited_primes.txt rename to tests/fixtures/tac/delimited_primes.txt diff --git a/test/fixtures/tac/delimited_primes_before.expected b/tests/fixtures/tac/delimited_primes_before.expected similarity index 100% rename from test/fixtures/tac/delimited_primes_before.expected rename to tests/fixtures/tac/delimited_primes_before.expected diff --git a/test/fixtures/tac/prime_per_line.expected b/tests/fixtures/tac/prime_per_line.expected similarity index 100% rename from test/fixtures/tac/prime_per_line.expected rename to tests/fixtures/tac/prime_per_line.expected diff --git a/test/fixtures/tac/prime_per_line.txt b/tests/fixtures/tac/prime_per_line.txt similarity index 100% rename from test/fixtures/tac/prime_per_line.txt rename to tests/fixtures/tac/prime_per_line.txt diff --git a/test/fixtures/tsort/call_graph.expected b/tests/fixtures/tsort/call_graph.expected similarity index 100% rename from test/fixtures/tsort/call_graph.expected rename to tests/fixtures/tsort/call_graph.expected diff --git a/test/fixtures/tsort/call_graph.txt b/tests/fixtures/tsort/call_graph.txt similarity index 100% rename from test/fixtures/tsort/call_graph.txt rename to tests/fixtures/tsort/call_graph.txt diff --git a/test/fixtures/wc/alice_in_wonderland.txt b/tests/fixtures/wc/alice_in_wonderland.txt similarity index 100% rename from test/fixtures/wc/alice_in_wonderland.txt rename to tests/fixtures/wc/alice_in_wonderland.txt diff --git a/test/fixtures/wc/lorem_ipsum.txt b/tests/fixtures/wc/lorem_ipsum.txt similarity index 100% rename from test/fixtures/wc/lorem_ipsum.txt rename to tests/fixtures/wc/lorem_ipsum.txt diff --git a/test/fixtures/wc/moby_dick.txt b/tests/fixtures/wc/moby_dick.txt similarity index 100% rename from test/fixtures/wc/moby_dick.txt rename to tests/fixtures/wc/moby_dick.txt diff --git a/tests/fold.rs b/tests/fold.rs new file mode 100644 index 000000000..f24c035ce --- /dev/null +++ b/tests/fold.rs @@ -0,0 +1,41 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "fold"; + +#[test] +fn test_default_80_column_wrap() { + let (at, mut ucmd) = testing(UTIL_NAME); + let out = ucmd.arg("lorem_ipsum.txt") + .run() + .stdout; + + assert_eq!(out, at.read("lorem_ipsum_80_column.expected")); +} + +#[test] +fn test_40_column_hard_cutoff() { + let (at, mut ucmd) = testing(UTIL_NAME); + let out = ucmd.arg("-w") + .arg("40") + .arg("lorem_ipsum.txt") + .run() + .stdout; + + assert_eq!(out, at.read("lorem_ipsum_40_column_hard.expected")); +} + +#[test] +fn test_40_column_word_boundary() { + let (at, mut ucmd) = testing(UTIL_NAME); + let out = ucmd.arg("-s") + .arg("-w") + .arg("40") + .arg("lorem_ipsum.txt") + .run() + .stdout; + + assert_eq!(out, at.read("lorem_ipsum_40_column_word.expected")); +} diff --git a/test/hashsum.rs b/tests/hashsum.rs similarity index 52% rename from test/hashsum.rs rename to tests/hashsum.rs index 38f300303..b0bb2929b 100644 --- a/test/hashsum.rs +++ b/tests/hashsum.rs @@ -1,8 +1,9 @@ -static PROGNAME: &'static str = "./hashsum"; - -#[path = "common/util.rs"] #[macro_use] -mod util; +mod common; + + + + macro_rules! get_hash( ($str:expr) => ( @@ -14,31 +15,30 @@ macro_rules! test_digest { ($($t:ident)*) => ($( mod $t { - use std::process::Command; - use util::*; - + use common::util::*; + static UTIL_NAME: &'static str = "hashsum"; static DIGEST_ARG: &'static str = concat!("--", stringify!($t)); static EXPECTED_FILE: &'static str = concat!(stringify!($t), ".expected"); #[test] fn test_single_file() { - let mut cmd = Command::new(::PROGNAME); - let result = run(&mut cmd.arg(DIGEST_ARG).arg("input.txt")); + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.arg(DIGEST_ARG).arg("input.txt").run(); assert_empty_stderr!(result); assert!(result.success); - assert_eq!(get_hash!(result.stdout), get_file_contents(EXPECTED_FILE)); + assert_eq!(get_hash!(result.stdout), at.read(EXPECTED_FILE)); } #[test] fn test_stdin() { - let input = get_file_contents("input.txt"); - let mut cmd = Command::new(::PROGNAME); - let result = run_piped_stdin(&mut cmd.arg(DIGEST_ARG), input); + let (at, mut ucmd) = testing(UTIL_NAME); + let input = at.read("input.txt"); + let result = ucmd.arg(DIGEST_ARG).run_piped_stdin(input); assert_empty_stderr!(result); assert!(result.success); - assert_eq!(get_hash!(result.stdout), get_file_contents(EXPECTED_FILE)); + assert_eq!(get_hash!(result.stdout), at.read(EXPECTED_FILE)); } } )*) diff --git a/tests/head.rs b/tests/head.rs new file mode 100644 index 000000000..19adbf6a0 --- /dev/null +++ b/tests/head.rs @@ -0,0 +1,75 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "head"; + +static INPUT: &'static str = "lorem_ipsum.txt"; + + +#[test] +fn test_stdin_default() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.run_piped_stdin(at.read(INPUT)); + assert_eq!(result.stdout, at.read("lorem_ipsum_default.expected")); +} + +#[test] +fn test_stdin_1_line_obsolete() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-1"]) + .run_piped_stdin(at.read(INPUT)); + assert_eq!(result.stdout, at.read("lorem_ipsum_1_line.expected")); +} + +#[test] +fn test_stdin_1_line() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-n", "1"]) + .run_piped_stdin(at.read(INPUT)); + assert_eq!(result.stdout, at.read("lorem_ipsum_1_line.expected")); +} + +#[test] +fn test_stdin_5_chars() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-c", "5"]) + .run_piped_stdin(at.read(INPUT)); + assert_eq!(result.stdout, at.read("lorem_ipsum_5_chars.expected")); +} + +#[test] +fn test_single_default() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.arg(INPUT).run(); + assert_eq!(result.stdout, at.read("lorem_ipsum_default.expected")); +} + +#[test] +fn test_single_1_line_obsolete() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-1", INPUT]).run(); + assert_eq!(result.stdout, at.read("lorem_ipsum_1_line.expected")); +} + +#[test] +fn test_single_1_line() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-n", "1", INPUT]).run(); + assert_eq!(result.stdout, at.read("lorem_ipsum_1_line.expected")); +} + +#[test] +fn test_single_5_chars() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-c", "5", INPUT]).run(); + assert_eq!(result.stdout, at.read("lorem_ipsum_5_chars.expected")); +} + +#[test] +fn test_verbose() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-v", INPUT]).run(); + assert_eq!(result.stdout, at.read("lorem_ipsum_verbose.expected")); +} diff --git a/tests/link.rs b/tests/link.rs new file mode 100644 index 000000000..b94fbeb28 --- /dev/null +++ b/tests/link.rs @@ -0,0 +1,53 @@ +#[macro_use] +mod common; + +extern crate libc; + +use common::util::*; + +static UTIL_NAME: &'static str = "link"; + +#[test] +fn test_link_existing_file() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file = "test_link_existing_file"; + let link = "test_link_existing_file_link"; + + at.touch(file); + at.write(file, "foobar"); + assert!(at.file_exists(file)); + + let result = ucmd.args(&[file, link]).run(); + + assert_empty_stderr!(result); + assert!(result.success); + assert!(at.file_exists(file)); + assert!(at.file_exists(link)); + assert_eq!(at.read(file), at.read(link)); +} + +#[test] +fn test_link_no_circular() { + let (at, mut ucmd) = testing(UTIL_NAME); + let link = "test_link_no_circular"; + + let result = ucmd.args(&[link, link]).run(); + assert_eq!(result.stderr, + "link: error: No such file or directory (os error 2)\n"); + assert!(!result.success); + assert!(!at.file_exists(link)); +} + +#[test] +fn test_link_nonexistent_file() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file = "test_link_nonexistent_file"; + let link = "test_link_nonexistent_file_link"; + + let result = ucmd.args(&[file, link]).run(); + assert_eq!(result.stderr, + "link: error: No such file or directory (os error 2)\n"); + assert!(!result.success); + assert!(!at.file_exists(file)); + assert!(!at.file_exists(link)); +} diff --git a/tests/ln.rs b/tests/ln.rs new file mode 100644 index 000000000..761571da1 --- /dev/null +++ b/tests/ln.rs @@ -0,0 +1,375 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "ln"; + + + +#[test] +fn test_symlink_existing_file() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file = "test_symlink_existing_file"; + let link = "test_symlink_existing_file_link"; + + at.touch(file); + + let result = ucmd.args(&["-s", file, link]).run(); + assert_empty_stderr!(result); + assert!(result.success); + assert!(at.file_exists(file)); + assert!(at.is_symlink(link)); + assert_eq!(at.resolve_link(link), file); +} + +#[test] +fn test_symlink_dangling_file() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file = "test_symlink_dangling_file"; + let link = "test_symlink_dangling_file_link"; + + let result = ucmd.args(&["-s", file, link]).run(); + assert_empty_stderr!(result); + assert!(result.success); + assert!(!at.file_exists(file)); + assert!(at.is_symlink(link)); + assert_eq!(at.resolve_link(link), file); +} + +#[test] +fn test_symlink_existing_directory() { + let (at, mut ucmd) = testing(UTIL_NAME); + let dir = "test_symlink_existing_dir"; + let link = "test_symlink_existing_dir_link"; + + at.mkdir(dir); + + let result = ucmd.args(&["-s", dir, link]).run(); + assert_empty_stderr!(result); + assert!(result.success); + assert!(at.dir_exists(dir)); + assert!(at.is_symlink(link)); + assert_eq!(at.resolve_link(link), dir); +} + +#[test] +fn test_symlink_dangling_directory() { + let (at, mut ucmd) = testing(UTIL_NAME); + let dir = "test_symlink_dangling_dir"; + let link = "test_symlink_dangling_dir_link"; + + let result = ucmd.args(&["-s", dir, link]).run(); + assert_empty_stderr!(result); + assert!(result.success); + assert!(!at.dir_exists(dir)); + assert!(at.is_symlink(link)); + assert_eq!(at.resolve_link(link), dir); +} + +#[test] +fn test_symlink_circular() { + let (at, mut ucmd) = testing(UTIL_NAME); + let link = "test_symlink_circular"; + + let result = ucmd.args(&["-s", link]).run(); + assert_empty_stderr!(result); + assert!(result.success); + assert!(at.is_symlink(link)); + assert_eq!(at.resolve_link(link), link); +} + +#[test] +fn test_symlink_dont_overwrite() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file = "test_symlink_dont_overwrite"; + let link = "test_symlink_dont_overwrite_link"; + + at.touch(file); + at.touch(link); + + let result = ucmd.args(&["-s", file, link]).run(); + assert!(!result.success); + assert!(at.file_exists(file)); + assert!(at.file_exists(link)); + assert!(!at.is_symlink(link)); +} + +#[test] +fn test_symlink_overwrite_force() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file_a = "test_symlink_overwrite_force_a"; + let file_b = "test_symlink_overwrite_force_b"; + let link = "test_symlink_overwrite_force_link"; + + // Create symlink + at.symlink(file_a, link); + assert!(at.is_symlink(link)); + assert_eq!(at.resolve_link(link), file_a); + + // Force overwrite of existing symlink + let result = ucmd.args(&["--force", "-s", file_b, link]).run(); + assert!(result.success); + assert!(at.is_symlink(link)); + assert_eq!(at.resolve_link(link), file_b); +} + +#[test] +fn test_symlink_interactive() { + let ts = TestSet::new(UTIL_NAME); + let at = &ts.fixtures; + let file = "test_symlink_interactive_file"; + let link = "test_symlink_interactive_file_link"; + + at.touch(file); + at.touch(link); + + let result1 = ts.util_cmd() + .args(&["-i", "-s", file, link]) + .run_piped_stdin(b"n"); + + assert_empty_stderr!(result1); + assert!(result1.success); + + assert!(at.file_exists(file)); + assert!(!at.is_symlink(link)); + + let result2 = ts.util_cmd() + .args(&["-i", "-s", file, link]) + .run_piped_stdin(b"Yesh"); + + assert_empty_stderr!(result2); + assert!(result2.success); + + assert!(at.file_exists(file)); + assert!(at.is_symlink(link)); + assert_eq!(at.resolve_link(link), file); +} + +#[test] +fn test_symlink_simple_backup() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file = "test_symlink_simple_backup"; + let link = "test_symlink_simple_backup_link"; + + at.touch(file); + at.symlink(file, link); + assert!(at.file_exists(file)); + assert!(at.is_symlink(link)); + assert_eq!(at.resolve_link(link), file); + + let result = ucmd.args(&["-b", "-s", file, link]).run(); + + assert_empty_stderr!(result); + assert!(result.success); + assert!(at.file_exists(file)); + + assert!(at.is_symlink(link)); + assert_eq!(at.resolve_link(link), file); + + let backup = &format!("{}~", link); + assert!(at.is_symlink(backup)); + assert_eq!(at.resolve_link(backup), file); +} + +#[test] +fn test_symlink_custom_backup_suffix() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file = "test_symlink_custom_backup_suffix"; + let link = "test_symlink_custom_backup_suffix_link"; + let suffix = "super-suffix-of-the-century"; + + at.touch(file); + at.symlink(file, link); + assert!(at.file_exists(file)); + assert!(at.is_symlink(link)); + assert_eq!(at.resolve_link(link), file); + + let arg = &format!("--suffix={}", suffix); + let result = ucmd.args(&["-b", arg, "-s", file, link]).run(); + + assert_empty_stderr!(result); + assert!(result.success); + assert!(at.file_exists(file)); + + assert!(at.is_symlink(link)); + assert_eq!(at.resolve_link(link), file); + + let backup = &format!("{}{}", link, suffix); + assert!(at.is_symlink(backup)); + assert_eq!(at.resolve_link(backup), file); +} + +#[test] +fn test_symlink_backup_numbering() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file = "test_symlink_backup_numbering"; + let link = "test_symlink_backup_numbering_link"; + + at.touch(file); + at.symlink(file, link); + assert!(at.file_exists(file)); + assert!(at.is_symlink(link)); + assert_eq!(at.resolve_link(link), file); + + let result = ucmd.args(&["-s", "--backup=t", file, link]).run(); + + assert_empty_stderr!(result); + assert!(result.success); + assert!(at.file_exists(file)); + + assert!(at.is_symlink(link)); + assert_eq!(at.resolve_link(link), file); + + let backup = &format!("{}.~1~", link); + assert!(at.is_symlink(backup)); + assert_eq!(at.resolve_link(backup), file); +} + +#[test] +fn test_symlink_existing_backup() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file = "test_symlink_existing_backup"; + let link = "test_symlink_existing_backup_link"; + let link_backup = "test_symlink_existing_backup_link.~1~"; + let resulting_backup = "test_symlink_existing_backup_link.~2~"; + + // Create symlink and verify + at.touch(file); + at.symlink(file, link); + assert!(at.file_exists(file)); + assert!(at.is_symlink(link)); + assert_eq!(at.resolve_link(link), file); + + // Create backup symlink and verify + at.symlink(file, link_backup); + assert!(at.file_exists(file)); + assert!(at.is_symlink(link_backup)); + assert_eq!(at.resolve_link(link_backup), file); + + let result = ucmd.args(&["-s", "--backup=nil", file, link]).run(); + + assert_empty_stderr!(result); + assert!(result.success); + assert!(at.file_exists(file)); + + assert!(at.is_symlink(link_backup)); + assert_eq!(at.resolve_link(link_backup), file); + + assert!(at.is_symlink(resulting_backup)); + assert_eq!(at.resolve_link(resulting_backup), file); +} + +#[test] +fn test_symlink_target_dir() { + let (at, mut ucmd) = testing(UTIL_NAME); + let dir = "test_ln_target_dir_dir"; + let file_a = "test_ln_target_dir_file_a"; + let file_b = "test_ln_target_dir_file_b"; + + at.touch(file_a); + at.touch(file_b); + at.mkdir(dir); + + let result = ucmd.args(&["-s", "-t", dir, file_a, file_b]).run(); + + assert_empty_stderr!(result); + assert!(result.success); + + let file_a_link = &format!("{}/{}", dir, file_a); + assert!(at.is_symlink(file_a_link)); + assert_eq!(at.resolve_link(file_a_link), file_a); + + let file_b_link = &format!("{}/{}", dir, file_b); + assert!(at.is_symlink(file_b_link)); + assert_eq!(at.resolve_link(file_b_link), file_b); +} + +#[test] +fn test_symlink_overwrite_dir() { + let (at, mut ucmd) = testing(UTIL_NAME); + let path_a = "test_symlink_overwrite_dir_a"; + let path_b = "test_symlink_overwrite_dir_b"; + + at.touch(path_a); + at.mkdir(path_b); + + let result = ucmd.args(&["-s", "-T", path_a, path_b]).run(); + + assert_empty_stderr!(result); + assert!(result.success); + + assert!(at.file_exists(path_a)); + assert!(at.is_symlink(path_b)); + assert_eq!(at.resolve_link(path_b), path_a); +} + +#[test] +fn test_symlink_overwrite_nonempty_dir() { + let (at, mut ucmd) = testing(UTIL_NAME); + let path_a = "test_symlink_overwrite_nonempty_dir_a"; + let path_b = "test_symlink_overwrite_nonempty_dir_b"; + let dummy = "test_symlink_overwrite_nonempty_dir_b/file"; + + at.touch(path_a); + at.mkdir(path_b); + at.touch(dummy); + + let result = ucmd.args(&["-v", "-T", "-s", path_a, path_b]).run(); + + // Not same error as GNU; the error message is a Rust builtin + // TODO: test (and implement) correct error message (or at least decide whether to do so) + // Current: "ln: error: Directory not empty (os error 66)" + // GNU: "ln: cannot link 'a' to 'b': Directory not empty" + assert!(result.stderr.len() > 0); + + // Verbose output for the link should not be shown on failure + assert!(result.stdout.len() == 0); + + assert!(!result.success); + assert!(at.file_exists(path_a)); + assert!(at.dir_exists(path_b)); +} + +#[test] +fn test_symlink_errors() { + let (at, mut ucmd) = testing(UTIL_NAME); + let dir = "test_symlink_errors_dir"; + let file_a = "test_symlink_errors_file_a"; + let file_b = "test_symlink_errors_file_b"; + + at.mkdir(dir); + at.touch(file_a); + at.touch(file_b); + + // $ ln -T -t a b + // ln: cannot combine --target-directory (-t) and --no-target-directory (-T) + let result = ucmd.args(&["-T", "-t", dir, file_a, file_b]).run(); + assert_eq!(result.stderr, + "ln: error: cannot combine --target-directory (-t) and --no-target-directory \ + (-T)\n"); + assert!(!result.success); +} + +#[test] +fn test_symlink_verbose() { + let ts = TestSet::new(UTIL_NAME); + let at = &ts.fixtures; + let file_a = "test_symlink_verbose_file_a"; + let file_b = "test_symlink_verbose_file_b"; + + at.touch(file_a); + + let result = ts.util_cmd().args(&["-v", file_a, file_b]).run(); + assert_empty_stderr!(result); + assert_eq!(result.stdout, format!("'{}' -> '{}'\n", file_b, file_a)); + assert!(result.success); + + at.touch(file_b); + + let result = ts.util_cmd().args(&["-v", "-b", file_a, file_b]).run(); + assert_empty_stderr!(result); + assert_eq!(result.stdout, + format!("'{}' -> '{}' (backup: '{}~')\n", file_b, file_a, file_b)); + assert!(result.success); +} diff --git a/tests/mkdir.rs b/tests/mkdir.rs new file mode 100644 index 000000000..e1b0dde90 --- /dev/null +++ b/tests/mkdir.rs @@ -0,0 +1,54 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "mkdir"; + +static TEST_DIR1: &'static str = "mkdir_test1"; +static TEST_DIR2: &'static str = "mkdir_test2"; +static TEST_DIR3: &'static str = "mkdir_test3"; +static TEST_DIR4: &'static str = "mkdir_test4/mkdir_test4_1"; +static TEST_DIR5: &'static str = "mkdir_test5/mkdir_test5_1"; + + +#[test] +fn test_mkdir_mkdir() { + let (_, mut ucmd) = testing(UTIL_NAME); + let exit_success = ucmd.arg(TEST_DIR1).run().success; + assert_eq!(exit_success, true); +} + +#[test] +fn test_mkdir_dup_dir() { + let ts = TestSet::new(UTIL_NAME); + let exit_success = ts.util_cmd().arg(TEST_DIR2).run().success; + let exit_success2 = ts.util_cmd().arg(TEST_DIR2).run().success; + assert!(exit_success); + assert!(!exit_success2); +} + +#[test] +fn test_mkdir_mode() { + let (_, mut ucmd) = testing(UTIL_NAME); + let exit_success = ucmd.arg("-m") + .arg("755") + .arg(TEST_DIR3) + .run() + .success; + assert!(exit_success); +} + +#[test] +fn test_mkdir_parent() { + let (_, mut ucmd) = testing(UTIL_NAME); + let exit_success = ucmd.arg("-p").arg(TEST_DIR4).run().success; + assert!(exit_success); +} + +#[test] +fn test_mkdir_no_parent() { + let (_, mut ucmd) = testing(UTIL_NAME); + let exit_success = ucmd.arg(TEST_DIR5).run().success; + assert!(!exit_success); +} diff --git a/tests/mod.rs b/tests/mod.rs new file mode 100644 index 000000000..34994bf5a --- /dev/null +++ b/tests/mod.rs @@ -0,0 +1 @@ +pub mod common; diff --git a/tests/mv.rs b/tests/mv.rs new file mode 100644 index 000000000..db39eed23 --- /dev/null +++ b/tests/mv.rs @@ -0,0 +1,480 @@ +#[macro_use] +mod common; + +extern crate libc; +extern crate time; +extern crate kernel32; +extern crate winapi; +extern crate filetime; + +use filetime::*; +use common::util::*; + +static UTIL_NAME: &'static str = "mv"; + +#[test] +fn test_mv_rename_dir() { + let (at, mut ucmd) = testing(UTIL_NAME); + let dir1 = "test_mv_rename_dir"; + let dir2 = "test_mv_rename_dir2"; + + at.mkdir(dir1); + + let result = ucmd.arg(dir1).arg(dir2).run(); + assert_empty_stderr!(result); + assert!(result.success); + + assert!(at.dir_exists(dir2)); +} + +#[test] +fn test_mv_rename_file() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file1 = "test_mv_rename_file"; + let file2 = "test_mv_rename_file2"; + + at.touch(file1); + + let result = ucmd.arg(file1).arg(file2).run(); + assert_empty_stderr!(result); + assert!(result.success); + + assert!(at.file_exists(file2)); +} + +#[test] +fn test_mv_move_file_into_dir() { + let (at, mut ucmd) = testing(UTIL_NAME); + let dir = "test_mv_move_file_into_dir_dir"; + let file = "test_mv_move_file_into_dir_file"; + + at.mkdir(dir); + at.touch(file); + + let result = ucmd.arg(file).arg(dir).run(); + assert_empty_stderr!(result); + assert!(result.success); + + assert!(at.file_exists(&format!("{}/{}", dir, file))); +} + +#[test] +fn test_mv_strip_slashes() { + let ts = TestSet::new(UTIL_NAME); + let at = &ts.fixtures; + let dir = "test_mv_strip_slashes_dir"; + let file = "test_mv_strip_slashes_file"; + let mut source = file.to_owned(); + source.push_str("/"); + + at.mkdir(dir); + at.touch(file); + + let result = ts.util_cmd().arg(&source).arg(dir).run(); + assert!(!result.success); + + assert!(!at.file_exists(&format!("{}/{}", dir, file))); + + let result = ts.util_cmd().arg("--strip-trailing-slashes").arg(source).arg(dir).run(); + assert_empty_stderr!(result); + assert!(result.success); + + assert!(at.file_exists(&format!("{}/{}", dir, file))); +} + +#[test] +fn test_mv_multiple_files() { + let (at, mut ucmd) = testing(UTIL_NAME); + let target_dir = "test_mv_multiple_files_dir"; + let file_a = "test_mv_multiple_file_a"; + let file_b = "test_mv_multiple_file_b"; + + at.mkdir(target_dir); + at.touch(file_a); + at.touch(file_b); + + let result = ucmd.arg(file_a).arg(file_b).arg(target_dir).run(); + assert_empty_stderr!(result); + assert!(result.success); + + assert!(at.file_exists(&format!("{}/{}", target_dir, file_a))); + assert!(at.file_exists(&format!("{}/{}", target_dir, file_b))); +} + +#[test] +fn test_mv_multiple_folders() { + let (at, mut ucmd) = testing(UTIL_NAME); + let target_dir = "test_mv_multiple_dirs_dir"; + let dir_a = "test_mv_multiple_dir_a"; + let dir_b = "test_mv_multiple_dir_b"; + + at.mkdir(target_dir); + at.mkdir(dir_a); + at.mkdir(dir_b); + + let result = ucmd.arg(dir_a).arg(dir_b).arg(target_dir).run(); + assert_empty_stderr!(result); + assert!(result.success); + + assert!(at.dir_exists(&format!("{}/{}", target_dir, dir_a))); + assert!(at.dir_exists(&format!("{}/{}", target_dir, dir_b))); +} + +#[test] +fn test_mv_interactive() { + let ts = TestSet::new(UTIL_NAME); + let at = &ts.fixtures; + let file_a = "test_mv_interactive_file_a"; + let file_b = "test_mv_interactive_file_b"; + + at.touch(file_a); + at.touch(file_b); + + + let result1 = ts.util_cmd().arg("-i").arg(file_a).arg(file_b).run_piped_stdin(b"n"); + + assert_empty_stderr!(result1); + assert!(result1.success); + + assert!(at.file_exists(file_a)); + assert!(at.file_exists(file_b)); + + + let result2 = ts.util_cmd().arg("-i").arg(file_a).arg(file_b).run_piped_stdin(b"Yesh"); + + assert_empty_stderr!(result2); + assert!(result2.success); + + assert!(!at.file_exists(file_a)); + assert!(at.file_exists(file_b)); +} + +#[test] +fn test_mv_no_clobber() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file_a = "test_mv_no_clobber_file_a"; + let file_b = "test_mv_no_clobber_file_b"; + + at.touch(file_a); + at.touch(file_b); + + let result = ucmd.arg("-n").arg(file_a).arg(file_b).run(); + assert_empty_stderr!(result); + assert!(result.success); + + assert!(at.file_exists(file_a)); + assert!(at.file_exists(file_b)); +} + +#[test] +fn test_mv_replace_file() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file_a = "test_mv_replace_file_a"; + let file_b = "test_mv_replace_file_b"; + + at.touch(file_a); + at.touch(file_b); + + let result = ucmd.arg(file_a).arg(file_b).run(); + assert_empty_stderr!(result); + assert!(result.success); + + assert!(!at.file_exists(file_a)); + assert!(at.file_exists(file_b)); +} + +#[test] +fn test_mv_force_replace_file() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file_a = "test_mv_force_replace_file_a"; + let file_b = "test_mv_force_replace_file_b"; + + at.touch(file_a); + at.touch(file_b); + + let result = ucmd.arg("--force").arg(file_a).arg(file_b).run(); + assert_empty_stderr!(result); + assert!(result.success); + + assert!(!at.file_exists(file_a)); + assert!(at.file_exists(file_b)); +} + +#[test] +fn test_mv_simple_backup() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file_a = "test_mv_simple_backup_file_a"; + let file_b = "test_mv_simple_backup_file_b"; + + at.touch(file_a); + at.touch(file_b); + let result = ucmd.arg("-b").arg(file_a).arg(file_b).run(); + + assert_empty_stderr!(result); + assert!(result.success); + + assert!(!at.file_exists(file_a)); + assert!(at.file_exists(file_b)); + assert!(at.file_exists(&format!("{}~", file_b))); +} + +#[test] +fn test_mv_custom_backup_suffix() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file_a = "test_mv_custom_backup_suffix_file_a"; + let file_b = "test_mv_custom_backup_suffix_file_b"; + let suffix = "super-suffix-of-the-century"; + + at.touch(file_a); + at.touch(file_b); + let result = ucmd.arg("-b") + .arg(format!("--suffix={}", suffix)) + .arg(file_a) + .arg(file_b) + .run(); + + assert_empty_stderr!(result); + assert!(result.success); + + assert!(!at.file_exists(file_a)); + assert!(at.file_exists(file_b)); + assert!(at.file_exists(&format!("{}{}", file_b, suffix))); +} + +#[test] +fn test_mv_backup_numbering() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file_a = "test_mv_backup_numbering_file_a"; + let file_b = "test_mv_backup_numbering_file_b"; + + at.touch(file_a); + at.touch(file_b); + let result = ucmd.arg("--backup=t").arg(file_a).arg(file_b).run(); + + assert_empty_stderr!(result); + assert!(result.success); + + assert!(!at.file_exists(file_a)); + assert!(at.file_exists(file_b)); + assert!(at.file_exists(&format!("{}.~1~", file_b))); +} + +#[test] +fn test_mv_existing_backup() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file_a = "test_mv_existing_backup_file_a"; + let file_b = "test_mv_existing_backup_file_b"; + let file_b_backup = "test_mv_existing_backup_file_b.~1~"; + let resulting_backup = "test_mv_existing_backup_file_b.~2~"; + + at.touch(file_a); + at.touch(file_b); + at.touch(file_b_backup); + let result = ucmd.arg("--backup=nil").arg(file_a).arg(file_b).run(); + + assert_empty_stderr!(result); + assert!(result.success); + + assert!(!at.file_exists(file_a)); + assert!(at.file_exists(file_b)); + assert!(at.file_exists(file_b_backup)); + assert!(at.file_exists(resulting_backup)); +} + +#[test] +fn test_mv_update_option() { + let test_set = TestSet::new(UTIL_NAME); + let at = &test_set.fixtures; + let file_a = "test_mv_update_option_file_a"; + let file_b = "test_mv_update_option_file_b"; + + at.touch(file_a); + at.touch(file_b); + let ts = time::now().to_timespec(); + let now = FileTime::from_seconds_since_1970(ts.sec as u64, ts.nsec as u32); + let later = FileTime::from_seconds_since_1970(ts.sec as u64 + 3600, ts.nsec as u32); + filetime::set_file_times(at.plus_as_string(file_a), now, now).unwrap(); + filetime::set_file_times(at.plus_as_string(file_b), now, later).unwrap(); + + let result1 = test_set.util_cmd().arg("--update").arg(file_a).arg(file_b).run(); + + assert_empty_stderr!(result1); + assert!(result1.success); + + assert!(at.file_exists(file_a)); + assert!(at.file_exists(file_b)); + + let result2 = test_set.util_cmd().arg("--update").arg(file_b).arg(file_a).run(); + + assert_empty_stderr!(result2); + assert!(result2.success); + + assert!(at.file_exists(file_a)); + assert!(!at.file_exists(file_b)); +} + +#[test] +fn test_mv_target_dir() { + let (at, mut ucmd) = testing(UTIL_NAME); + let dir = "test_mv_target_dir_dir"; + let file_a = "test_mv_target_dir_file_a"; + let file_b = "test_mv_target_dir_file_b"; + + at.touch(file_a); + at.touch(file_b); + at.mkdir(dir); + let result = ucmd.arg("-t").arg(dir).arg(file_a).arg(file_b).run(); + + assert_empty_stderr!(result); + assert!(result.success); + + assert!(!at.file_exists(file_a)); + assert!(!at.file_exists(file_b)); + assert!(at.file_exists(&format!("{}/{}", dir, file_a))); + assert!(at.file_exists(&format!("{}/{}", dir, file_b))); +} + +#[test] +fn test_mv_overwrite_dir() { + let (at, mut ucmd) = testing(UTIL_NAME); + let dir_a = "test_mv_overwrite_dir_a"; + let dir_b = "test_mv_overwrite_dir_b"; + + at.mkdir(dir_a); + at.mkdir(dir_b); + let result = ucmd.arg("-T").arg(dir_a).arg(dir_b).run(); + + assert_empty_stderr!(result); + assert!(result.success); + + assert!(!at.dir_exists(dir_a)); + assert!(at.dir_exists(dir_b)); +} + +#[test] +fn test_mv_overwrite_nonempty_dir() { + let (at, mut ucmd) = testing(UTIL_NAME); + let dir_a = "test_mv_overwrite_nonempty_dir_a"; + let dir_b = "test_mv_overwrite_nonempty_dir_b"; + let dummy = "test_mv_overwrite_nonempty_dir_b/file"; + + at.mkdir(dir_a); + at.mkdir(dir_b); + at.touch(dummy); + let result = ucmd.arg("-vT").arg(dir_a).arg(dir_b).run(); + + // Not same error as GNU; the error message is a rust builtin + // TODO: test (and implement) correct error message (or at least decide whether to do so) + // Current: "mv: error: couldn't rename path (Directory not empty; from=a; to=b)" + // GNU: "mv: cannot move ‘a’ to ‘b’: Directory not empty" + assert!(result.stderr.len() > 0); + + // Verbose output for the move should not be shown on failure + assert!(result.stdout.len() == 0); + + assert!(!result.success); + assert!(at.dir_exists(dir_a)); + assert!(at.dir_exists(dir_b)); +} + +#[test] +fn test_mv_backup_dir() { + let (at, mut ucmd) = testing(UTIL_NAME); + let dir_a = "test_mv_backup_dir_dir_a"; + let dir_b = "test_mv_backup_dir_dir_b"; + + at.mkdir(dir_a); + at.mkdir(dir_b); + let result = ucmd.arg("-vbT").arg(dir_a).arg(dir_b).run(); + + assert_empty_stderr!(result); + assert_eq!(result.stdout, + format!("‘{}’ -> ‘{}’ (backup: ‘{}~’)\n", + dir_a, + dir_b, + dir_b)); + assert!(result.success); + + assert!(!at.dir_exists(dir_a)); + assert!(at.dir_exists(dir_b)); + assert!(at.dir_exists(&format!("{}~", dir_b))); +} + +#[test] +fn test_mv_errors() { + let ts = TestSet::new(UTIL_NAME); + let at = &ts.fixtures; + let dir = "test_mv_errors_dir"; + let file_a = "test_mv_errors_file_a"; + let file_b = "test_mv_errors_file_b"; + at.mkdir(dir); + at.touch(file_a); + at.touch(file_b); + + // $ mv -T -t a b + // mv: cannot combine --target-directory (-t) and --no-target-directory (-T) + let result = ts.util_cmd().arg("-T").arg("-t").arg(dir).arg(file_a).arg(file_b).run(); + assert_eq!(result.stderr, + "mv: error: cannot combine --target-directory (-t) and --no-target-directory \ + (-T)\n"); + assert!(!result.success); + + + // $ at.touch file && at.mkdir dir + // $ mv -T file dir + // err == mv: cannot overwrite directory ‘dir’ with non-directory + let result = ts.util_cmd().arg("-T").arg(file_a).arg(dir).run(); + assert_eq!(result.stderr, + format!("mv: error: cannot overwrite directory ‘{}’ with non-directory\n", + dir)); + assert!(!result.success); + + // $ at.mkdir dir && at.touch file + // $ mv dir file + // err == mv: cannot overwrite non-directory ‘file’ with directory ‘dir’ + let result = ts.util_cmd().arg(dir).arg(file_a).run(); + assert!(result.stderr.len() > 0); + assert!(!result.success); +} + +#[test] +fn test_mv_verbose() { + let ts = TestSet::new(UTIL_NAME); + let at = &ts.fixtures; + let dir = "test_mv_verbose_dir"; + let file_a = "test_mv_verbose_file_a"; + let file_b = "test_mv_verbose_file_b"; + at.mkdir(dir); + at.touch(file_a); + at.touch(file_b); + + let result = ts.util_cmd().arg("-v").arg(file_a).arg(file_b).run(); + assert_empty_stderr!(result); + assert_eq!(result.stdout, + format!("‘{}’ -> ‘{}’\n", file_a, file_b)); + assert!(result.success); + + + at.touch(file_a); + let result = ts.util_cmd().arg("-vb").arg(file_a).arg(file_b).run(); + assert_empty_stderr!(result); + assert_eq!(result.stdout, + format!("‘{}’ -> ‘{}’ (backup: ‘{}~’)\n", + file_a, + file_b, + file_b)); + assert!(result.success); +} + +// Todo: + +// $ at.touch a b +// $ chmod -w b +// $ ll +// total 0 +// -rw-rw-r-- 1 user user 0 okt 25 11:21 a +// -r--r--r-- 1 user user 0 okt 25 11:21 b +// $ +// $ mv -v a b +// mv: try to overwrite ‘b’, overriding mode 0444 (r--r--r--)? y +// ‘a’ -> ‘b’ diff --git a/tests/nl.rs b/tests/nl.rs new file mode 100644 index 000000000..a555e4b09 --- /dev/null +++ b/tests/nl.rs @@ -0,0 +1,58 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "nl"; + +#[test] +fn test_stdin_nonewline() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.run_piped_stdin("No Newline".as_bytes()); + assert_eq!(result.stdout, " 1\tNo Newline\n"); +} +#[test] +fn test_stdin_newline() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-s", "-", "-w", "1"]) + .run_piped_stdin("Line One\nLine Two\n".as_bytes()); + assert_eq!(result.stdout, "1-Line One\n2-Line Two\n"); +} + +#[test] +fn test_padding_without_overflow() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-i", "1000", "-s", "x", "-n", "rz", "simple.txt"]).run(); + assert_eq!(result.stdout, + "000001xL1\n001001xL2\n002001xL3\n003001xL4\n004001xL5\n005001xL6\n006001xL7\n0070\ + 01xL8\n008001xL9\n009001xL10\n010001xL11\n011001xL12\n012001xL13\n013001xL14\n014\ + 001xL15\n"); +} + +#[test] +fn test_padding_with_overflow() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-i", "1000", "-s", "x", "-n", "rz", "-w", "4", "simple.txt"]).run(); + assert_eq!(result.stdout, + "0001xL1\n1001xL2\n2001xL3\n3001xL4\n4001xL5\n5001xL6\n6001xL7\n7001xL8\n8001xL9\n\ + 9001xL10\n10001xL11\n11001xL12\n12001xL13\n13001xL14\n14001xL15\n"); +} + +#[test] +fn test_sections_and_styles() { + for &(fixture, output) in [("section.txt", + "\nHEADER1\nHEADER2\n\n1 |BODY1\n2 \ + |BODY2\n\nFOOTER1\nFOOTER2\n\nNEXTHEADER1\nNEXTHEADER2\n\n1 \ + |NEXTBODY1\n2 |NEXTBODY2\n\nNEXTFOOTER1\nNEXTFOOTER2\n"), + ("joinblanklines.txt", + "1 |Nonempty\n2 |Nonempty\n3 |Followed by 10x empty\n\n\n\n\n4 \ + |\n\n\n\n\n5 |\n6 |Followed by 5x empty\n\n\n\n\n7 |\n8 \ + |Followed by 4x empty\n\n\n\n\n9 |Nonempty\n10 |Nonempty\n11 \ + |Nonempty.\n")] + .iter() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-s", "|", "-n", "ln", "-w", "3", "-b", "a", "-l", "5", fixture]) + .run(); + assert_eq!(result.stdout, output); + } +} diff --git a/tests/paste.rs b/tests/paste.rs new file mode 100644 index 000000000..66e052d96 --- /dev/null +++ b/tests/paste.rs @@ -0,0 +1,19 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "paste"; + +#[test] +fn test_combine_pairs_of_lines() { + let (at, mut ucmd) = testing(UTIL_NAME); + let out = ucmd.arg("-s") + .arg("-d") + .arg("\t\n") + .arg("html_colors.txt") + .run() + .stdout; + + assert_eq!(out, at.read("html_colors.expected")); +} diff --git a/test/ptx.rs b/tests/ptx.rs similarity index 81% rename from test/ptx.rs rename to tests/ptx.rs index 1c4d4e730..1aa1677eb 100644 --- a/test/ptx.rs +++ b/tests/ptx.rs @@ -1,11 +1,9 @@ -use std::process::Command; -use util::*; - -static PROGNAME: &'static str = "./ptx"; - -#[path = "common/util.rs"] #[macro_use] -mod util; +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "ptx"; #[test] fn gnu_ext_disabled_roff_no_ref() { @@ -50,9 +48,9 @@ fn gnu_ext_disabled_ignore_and_only_file() { } fn test_ptx(opts: &Vec<&str>, expected: &str) { - let mut ptx = Command::new(PROGNAME); - let result = run(&mut ptx.args(opts).arg("input")); + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(opts).arg("input").run(); assert!(result.success); - assert_eq!(result.stdout, get_file_contents(expected)); + assert_eq!(result.stdout, at.read(expected)); assert_empty_stderr!(&result); } diff --git a/tests/pwd.rs b/tests/pwd.rs new file mode 100644 index 000000000..b813548f8 --- /dev/null +++ b/tests/pwd.rs @@ -0,0 +1,16 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "pwd"; + + +#[test] +fn test_default() { + let (at, mut ucmd) = testing(UTIL_NAME); + let out = ucmd.run().stdout; + + let expected = at.root_dir(); + assert_eq!(out.trim_right(), expected); +} diff --git a/tests/readlink.rs b/tests/readlink.rs new file mode 100644 index 000000000..27d76a583 --- /dev/null +++ b/tests/readlink.rs @@ -0,0 +1,74 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "readlink"; + +static GIBBERISH: &'static str = "supercalifragilisticexpialidocious"; + + +#[test] +fn test_canonicalize() { + let (at, mut ucmd) = testing(UTIL_NAME); + let out = ucmd.arg("-f") + .arg(".") + .run() + .stdout; + + assert_eq!(out.trim_right(), at.root_dir()); +} + +#[test] +fn test_canonicalize_existing() { + let (at, mut ucmd) = testing(UTIL_NAME); + let out = ucmd.arg("-e") + .arg(".") + .run() + .stdout; + + assert_eq!(out.trim_right(), at.root_dir()); +} + +#[test] +fn test_canonicalize_missing() { + let (at, mut ucmd) = testing(UTIL_NAME); + let mut expected = at.root_dir(); + expected.push_str("/"); + expected.push_str(GIBBERISH); + + let out = ucmd.arg("-m") + .arg(GIBBERISH) + .run() + .stdout; + + assert_eq!(out.trim_right(), expected); +} + +#[test] +fn test_long_redirection_to_current_dir() { + let (at, mut ucmd) = testing(UTIL_NAME); + // Create a 256-character path to current directory + let dir = repeat_str("./", 128); + let out = ucmd.arg("-n") + .arg("-m") + .arg(dir) + .run() + .stdout; + + assert_eq!(out, at.root_dir()); +} + +#[test] +fn test_long_redirection_to_root() { + let (_, mut ucmd) = testing(UTIL_NAME); + // Create a 255-character path to root + let dir = repeat_str("../", 85); + let out = ucmd.arg("-n") + .arg("-m") + .arg(dir) + .run() + .stdout; + + assert_eq!(out, "/"); +} diff --git a/tests/realpath.rs b/tests/realpath.rs new file mode 100644 index 000000000..8eafe0e2d --- /dev/null +++ b/tests/realpath.rs @@ -0,0 +1,34 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "realpath"; + +#[test] +fn test_current_directory() { + let (at, mut ucmd) = testing(UTIL_NAME); + let out = ucmd.arg(".").run().stdout; + + assert_eq!(out.trim_right(), at.root_dir()); +} + +#[test] +fn test_long_redirection_to_current_dir() { + let (at, mut ucmd) = testing(UTIL_NAME); + // Create a 256-character path to current directory + let dir = repeat_str("./", 128); + let out = ucmd.arg(dir).run().stdout; + + assert_eq!(out.trim_right(), at.root_dir()); +} + +#[test] +fn test_long_redirection_to_root() { + let (_, mut ucmd) = testing(UTIL_NAME); + // Create a 255-character path to root + let dir = repeat_str("../", 85); + let out = ucmd.arg(dir).run().stdout; + + assert_eq!(out.trim_right(), "/"); +} diff --git a/tests/rm.rs b/tests/rm.rs new file mode 100644 index 000000000..91dba21ff --- /dev/null +++ b/tests/rm.rs @@ -0,0 +1,158 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "rm"; + +#[test] +fn test_rm_one_file() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file = "test_rm_one_file"; + + at.touch(file); + + let result = ucmd.arg(file).run(); + assert_empty_stderr!(result); + assert!(result.success); + + assert!(!at.file_exists(file)); +} + +#[test] +fn test_rm_multiple_files() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file_a = "test_rm_multiple_file_a"; + let file_b = "test_rm_multiple_file_b"; + + at.touch(file_a); + at.touch(file_b); + + let result = ucmd.arg(file_a).arg(file_b).run(); + assert_empty_stderr!(result); + assert!(result.success); + + assert!(!at.file_exists(file_a)); + assert!(!at.file_exists(file_b)); +} + +#[test] +fn test_rm_interactive() { + let ts = TestSet::new(UTIL_NAME); + let at = &ts.fixtures; + + let file_a = "test_rm_interactive_file_a"; + let file_b = "test_rm_interactive_file_b"; + + at.touch(file_a); + at.touch(file_b); + + let result1 = ts.util_cmd() + .arg("-i") + .arg(file_a) + .arg(file_b) + .run_piped_stdin(b"n"); + + assert!(result1.success); + + assert!(at.file_exists(file_a)); + assert!(at.file_exists(file_b)); + + let result2 = ts.util_cmd() + .arg("-i") + .arg(file_a) + .arg(file_b) + .run_piped_stdin(b"Yesh"); + + assert!(result2.success); + + assert!(!at.file_exists(file_a)); + assert!(at.file_exists(file_b)); +} + +#[test] +fn test_rm_force() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file_a = "test_rm_force_a"; + let file_b = "test_rm_force_b"; + + let result = ucmd.arg("-f") + .arg(file_a) + .arg(file_b) + .run(); + assert_empty_stderr!(result); + assert!(result.success); + + assert!(!at.file_exists(file_a)); + assert!(!at.file_exists(file_b)); +} + +#[test] +fn test_rm_empty_directory() { + let (at, mut ucmd) = testing(UTIL_NAME); + let dir = "test_rm_empty_directory"; + + at.mkdir(dir); + + let result = ucmd.arg("-d").arg(dir).run(); + assert_empty_stderr!(result); + assert!(result.success); + + assert!(!at.dir_exists(dir)); +} + +#[test] +fn test_rm_recursive() { + let (at, mut ucmd) = testing(UTIL_NAME); + let dir = "test_rm_recursive_directory"; + let file_a = "test_rm_recursive_directory/test_rm_recursive_file_a"; + let file_b = "test_rm_recursive_directory/test_rm_recursive_file_b"; + + at.mkdir(dir); + at.touch(file_a); + at.touch(file_b); + + let result = ucmd.arg("-r").arg(dir).run(); + assert_empty_stderr!(result); + assert!(result.success); + + assert!(!at.dir_exists(dir)); + assert!(!at.file_exists(file_a)); + assert!(!at.file_exists(file_b)); +} + +#[test] +fn test_rm_errors() { + let (at, mut ucmd) = testing(UTIL_NAME); + let dir = "test_rm_errors_directory"; + let file_a = "test_rm_errors_directory/test_rm_errors_file_a"; + let file_b = "test_rm_errors_directory/test_rm_errors_file_b"; + + at.mkdir(dir); + at.touch(file_a); + at.touch(file_b); + + // $ rm test_rm_errors_directory + // rm: error: could not remove directory 'test_rm_errors_directory' (did you mean to pass '-r'?) + let result = ucmd.arg(dir).run(); + assert_eq!(result.stderr, + "rm: error: could not remove directory 'test_rm_errors_directory' (did you mean \ + to pass '-r'?)\n"); + assert!(!result.success); +} + +#[test] +fn test_rm_verbose() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file_a = "test_rm_verbose_file_a"; + let file_b = "test_rm_verbose_file_b"; + + at.touch(file_a); + at.touch(file_b); + + let result = ucmd.arg("-v").arg(file_a).arg(file_b).run(); + assert_empty_stderr!(result); + assert_eq!(result.stdout, + format!("removed '{}'\nremoved '{}'\n", file_a, file_b)); + assert!(result.success); +} diff --git a/tests/rmdir.rs b/tests/rmdir.rs new file mode 100644 index 000000000..d114d6eda --- /dev/null +++ b/tests/rmdir.rs @@ -0,0 +1,120 @@ +#[macro_use] +mod common; + +extern crate libc; + +use common::util::*; + +static UTIL_NAME: &'static str = "rmdir"; + +#[test] +fn test_rmdir_empty_directory_no_parents() { + let (at, mut ucmd) = testing(UTIL_NAME); + let dir = "test_rmdir_empty_no_parents"; + + at.mkdir(dir); + assert!(at.dir_exists(dir)); + + let result = ucmd.arg(dir).run(); + assert_empty_stderr!(result); + assert!(result.success); + + assert!(!at.dir_exists(dir)); +} + +#[test] +fn test_rmdir_empty_directory_with_parents() { + let (at, mut ucmd) = testing(UTIL_NAME); + let dir = "test_rmdir_empty/with/parents"; + + at.mkdir_all(dir); + assert!(at.dir_exists(dir)); + + let result = ucmd.arg("-p").arg(dir).run(); + assert_empty_stderr!(result); + assert!(result.success); + + assert!(!at.dir_exists(dir)); +} + +#[test] +fn test_rmdir_nonempty_directory_no_parents() { + let (at, mut ucmd) = testing(UTIL_NAME); + let dir = "test_rmdir_nonempty_no_parents"; + let file = "test_rmdir_nonempty_no_parents/foo"; + + at.mkdir(dir); + assert!(at.dir_exists(dir)); + + at.touch(file); + assert!(at.file_exists(file)); + + let result = ucmd.arg(dir).run(); + assert_eq!(result.stderr, + "rmdir: error: failed to remove 'test_rmdir_nonempty_no_parents': Directory not \ + empty\n"); + assert!(!result.success); + + assert!(at.dir_exists(dir)); +} + +#[test] +fn test_rmdir_nonempty_directory_with_parents() { + let (at, mut ucmd) = testing(UTIL_NAME); + let dir = "test_rmdir_nonempty/with/parents"; + let file = "test_rmdir_nonempty/with/parents/foo"; + + at.mkdir_all(dir); + assert!(at.dir_exists(dir)); + + at.touch(file); + assert!(at.file_exists(file)); + + let result = ucmd.arg("-p").arg(dir).run(); + assert_eq!(result.stderr, + "rmdir: error: failed to remove 'test_rmdir_nonempty/with/parents': Directory not \ + empty\nrmdir: error: failed to remove 'test_rmdir_nonempty/with': Directory not \ + empty\nrmdir: error: failed to remove 'test_rmdir_nonempty': Directory not \ + empty\n"); + assert!(!result.success); + + assert!(at.dir_exists(dir)); +} + +#[test] +fn test_rmdir_ignore_nonempty_directory_no_parents() { + let (at, mut ucmd) = testing(UTIL_NAME); + let dir = "test_rmdir_ignore_nonempty_no_parents"; + let file = "test_rmdir_ignore_nonempty_no_parents/foo"; + + at.mkdir(dir); + assert!(at.dir_exists(dir)); + + at.touch(file); + assert!(at.file_exists(file)); + + let result = ucmd.arg("--ignore-fail-on-non-empty").arg(dir).run(); + assert_empty_stderr!(result); + assert!(result.success); + + assert!(at.dir_exists(dir)); +} + +#[test] +fn test_rmdir_ignore_nonempty_directory_with_parents() { + let (at, mut ucmd) = testing(UTIL_NAME); + let dir = "test_rmdir_ignore_nonempty/with/parents"; + let file = "test_rmdir_ignore_nonempty/with/parents/foo"; + + at.mkdir_all(dir); + assert!(at.dir_exists(dir)); + + at.touch(file); + assert!(at.file_exists(file)); + + let result = ucmd.arg("--ignore-fail-on-non-empty").arg("-p").arg(dir).run(); + assert_empty_stderr!(result); + assert!(result.success); + + assert!(at.dir_exists(dir)); +} diff --git a/tests/seq.rs b/tests/seq.rs new file mode 100644 index 000000000..755bd4ad6 --- /dev/null +++ b/tests/seq.rs @@ -0,0 +1,34 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "seq"; + +#[test] +fn test_count_up() { + let (_, mut ucmd) = testing(UTIL_NAME); + let out = ucmd.args(&["10"]).run().stdout; + assert_eq!(out, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n"); +} + +#[test] +fn test_count_down() { + let (_, mut ucmd) = testing(UTIL_NAME); + let out = ucmd.args(&["--", "5", "-1", "1"]).run().stdout; + assert_eq!(out, "5\n4\n3\n2\n1\n"); +} + +#[test] +fn test_separator_and_terminator() { + let (_, mut ucmd) = testing(UTIL_NAME); + let out = ucmd.args(&["-s", ",", "-t", "!", "2", "6"]).run().stdout; + assert_eq!(out, "2,3,4,5,6!"); +} + +#[test] +fn test_equalize_widths() { + let (_, mut ucmd) = testing(UTIL_NAME); + let out = ucmd.args(&["-w", "5", "10"]).run().stdout; + assert_eq!(out, "05\n06\n07\n08\n09\n10\n"); +} diff --git a/tests/sort.rs b/tests/sort.rs new file mode 100644 index 000000000..3ebb87f6c --- /dev/null +++ b/tests/sort.rs @@ -0,0 +1,55 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "sort"; + + +#[test] +fn numeric1() { + numeric_helper(1); +} + +#[test] +fn numeric2() { + numeric_helper(2); +} + +#[test] +fn numeric3() { + numeric_helper(3); +} + +#[test] +fn numeric4() { + numeric_helper(4); +} + +#[test] +fn numeric5() { + numeric_helper(5); +} + +#[test] +fn numeric6() { + numeric_helper(6); +} + +#[test] +fn human1() { + test_helper(&String::from("human1"), &String::from("-H")); +} + +fn numeric_helper(test_num: isize) { + test_helper(&format!("numeric{}", test_num), &String::from("-n")) +} + +fn test_helper(file_name: &String, args: &String) { + let (at, mut ucmd) = testing(UTIL_NAME); + ucmd.arg(args); + let out = ucmd.arg(format!("{}{}", file_name, ".txt")).run().stdout; + + let filename = format!("{}{}", file_name, ".ans"); + assert_eq!(out, at.read(&filename)); +} diff --git a/tests/split.rs b/tests/split.rs new file mode 100644 index 000000000..0825a3e44 --- /dev/null +++ b/tests/split.rs @@ -0,0 +1,151 @@ +#[macro_use] +mod common; + +extern crate rand; +extern crate regex; + +use std::fs::{File, read_dir}; +use std::io::{Read, Write}; +use std::path::Path; +use rand::{Rng, thread_rng}; +use regex::Regex; +use common::util::*; + +static UTIL_NAME: &'static str = "split"; + + + +fn random_chars(n: usize) -> String { + thread_rng().gen_ascii_chars().take(n).collect::() +} + +struct Glob { + directory: AtPath, + regex: Regex, +} + +impl Glob { + fn new(at: &AtPath, directory: &str, regex: &str) -> Glob { + Glob { + directory: AtPath::new(Path::new(&at.plus_as_string(directory))), + regex: Regex::new(regex).unwrap(), + } + } + + fn count(&self) -> usize { + self.collect().len() + } + + fn collect(&self) -> Vec { + read_dir(Path::new(&self.directory.subdir)) + .unwrap() + .filter_map(|entry| { + let path = entry.unwrap().path(); + let name = self.directory.minus_as_string(path.as_path().to_str().unwrap_or("")); + if self.regex.is_match(&name) { + Some(name) + } else { + None + } + }) + .collect() + } + + fn collate(&self) -> Vec { + let mut files = self.collect(); + files.sort(); + let mut data: Vec = vec![]; + for name in files.iter() { + data.extend(self.directory.read(name).into_bytes()); + } + data + } +} + +struct RandomFile { + inner: File, +} + +impl RandomFile { + fn new(at: &AtPath, name: &str) -> RandomFile { + RandomFile { inner: File::create(&at.plus(name)).unwrap() } + } + + fn add_bytes(&mut self, bytes: usize) { + let chunk_size: usize = if bytes >= 1024 { + 1024 + } else { + bytes + }; + let mut n = bytes; + while n > chunk_size { + let _ = write!(self.inner, "{}", random_chars(chunk_size)); + n -= chunk_size; + } + let _ = write!(self.inner, "{}", random_chars(n)); + } + + fn add_lines(&mut self, lines: usize) { + let line_size: usize = 32; + let mut n = lines; + while n > 0 { + let _ = writeln!(self.inner, "{}", random_chars(line_size)); + n -= 1; + } + } +} + +#[test] +fn test_split_default() { + let (at, mut ucmd) = testing(UTIL_NAME); + let name = "split_default"; + let glob = Glob::new(&at, ".", r"x[:alpha:][:alpha:]$"); + RandomFile::new(&at, name).add_lines(2000); + assert!(ucmd.args(&[name]).run().success); + assert_eq!(glob.count(), 2); + assert_eq!(glob.collate(), at.read(name).into_bytes()); +} + +#[test] +fn test_split_num_prefixed_chunks_by_bytes() { + let (at, mut ucmd) = testing(UTIL_NAME); + let name = "split_num_prefixed_chunks_by_bytes"; + let glob = Glob::new(&at, ".", r"a\d\d$"); + RandomFile::new(&at, name).add_bytes(10000); + assert!(ucmd.args(&["-d", "-b", "1000", name, "a"]).run().success); + assert_eq!(glob.count(), 10); + assert_eq!(glob.collate(), at.read(name).into_bytes()); +} + +#[test] +fn test_split_str_prefixed_chunks_by_bytes() { + let (at, mut ucmd) = testing(UTIL_NAME); + let name = "split_str_prefixed_chunks_by_bytes"; + let glob = Glob::new(&at, ".", r"b[:alpha:][:alpha:]$"); + RandomFile::new(&at, name).add_bytes(10000); + assert!(ucmd.args(&["-b", "1000", name, "b"]).run().success); + assert_eq!(glob.count(), 10); + assert_eq!(glob.collate(), at.read(name).into_bytes()); +} + +#[test] +fn test_split_num_prefixed_chunks_by_lines() { + let (at, mut ucmd) = testing(UTIL_NAME); + let name = "split_num_prefixed_chunks_by_lines"; + let glob = Glob::new(&at, ".", r"c\d\d$"); + RandomFile::new(&at, name).add_lines(10000); + assert!(ucmd.args(&["-d", "-l", "1000", name, "c"]).run().success); + assert_eq!(glob.count(), 10); + assert_eq!(glob.collate(), at.read(name).into_bytes()); +} + +#[test] +fn test_split_str_prefixed_chunks_by_lines() { + let (at, mut ucmd) = testing(UTIL_NAME); + let name = "split_str_prefixed_chunks_by_lines"; + let glob = Glob::new(&at, ".", r"d[:alpha:][:alpha:]$"); + RandomFile::new(&at, name).add_lines(10000); + assert!(ucmd.args(&["-l", "1000", name, "d"]).run().success); + assert_eq!(glob.count(), 10); + assert_eq!(glob.collate(), at.read(name).into_bytes()); +} diff --git a/tests/stdbuf.rs b/tests/stdbuf.rs new file mode 100644 index 000000000..81e1a31b0 --- /dev/null +++ b/tests/stdbuf.rs @@ -0,0 +1,16 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "stdbuf"; + +#[test] +fn test_stdbuf_unbuffered_stdout() { + let (_, mut ucmd) = testing(UTIL_NAME); + // This is a basic smoke test + let result = ucmd.args(&["-o0", "head"]) + .run_piped_stdin("The quick brown fox jumps over the lazy dog."); + assert_eq!(result.stdout, + "The quick brown fox jumps over the lazy dog."); +} diff --git a/tests/sum.rs b/tests/sum.rs new file mode 100644 index 000000000..eeb8c1f05 --- /dev/null +++ b/tests/sum.rs @@ -0,0 +1,73 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "sum"; + +#[test] +fn test_bsd_single_file() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.arg("lorem_ipsum.txt").run(); + + assert_empty_stderr!(result); + assert!(result.success); + assert_eq!(result.stdout, at.read("bsd_single_file.expected")); +} + +#[test] +fn test_bsd_multiple_files() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.arg("lorem_ipsum.txt") + .arg("alice_in_wonderland.txt") + .run(); + + assert_empty_stderr!(result); + assert!(result.success); + assert_eq!(result.stdout, at.read("bsd_multiple_files.expected")); +} + +#[test] +fn test_bsd_stdin() { + let (at, mut ucmd) = testing(UTIL_NAME); + let input = at.read("lorem_ipsum.txt"); + let result = ucmd.run_piped_stdin(input); + + assert_empty_stderr!(result); + assert!(result.success); + assert_eq!(result.stdout, at.read("bsd_stdin.expected")); +} + +#[test] +fn test_sysv_single_file() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.arg("-s").arg("lorem_ipsum.txt").run(); + + assert_empty_stderr!(result); + assert!(result.success); + assert_eq!(result.stdout, at.read("sysv_single_file.expected")); +} + +#[test] +fn test_sysv_multiple_files() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.arg("-s") + .arg("lorem_ipsum.txt") + .arg("alice_in_wonderland.txt") + .run(); + + assert_empty_stderr!(result); + assert!(result.success); + assert_eq!(result.stdout, at.read("sysv_multiple_files.expected")); +} + +#[test] +fn test_sysv_stdin() { + let (at, mut ucmd) = testing(UTIL_NAME); + let input = at.read("lorem_ipsum.txt"); + let result = ucmd.run_piped_stdin(input); + + assert_empty_stderr!(result); + assert!(result.success); + assert_eq!(result.stdout, at.read("sysv_stdin.expected")); +} diff --git a/tests/tac.rs b/tests/tac.rs new file mode 100644 index 000000000..ee64c65ca --- /dev/null +++ b/tests/tac.rs @@ -0,0 +1,48 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "tac"; + +#[test] +fn test_stdin_default() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.run_piped_stdin("100\n200\n300\n400\n500"); + assert_eq!(result.stdout, "500400\n300\n200\n100\n"); +} + +#[test] +fn test_stdin_non_newline_separator() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-s", ":"]).run_piped_stdin("100:200:300:400:500"); + assert_eq!(result.stdout, "500400:300:200:100:"); +} + +#[test] +fn test_stdin_non_newline_separator_before() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-b", "-s", ":"]).run_piped_stdin("100:200:300:400:500"); + assert_eq!(result.stdout, "500:400:300:200:100"); +} + +#[test] +fn test_single_default() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.arg("prime_per_line.txt").run(); + assert_eq!(result.stdout, at.read("prime_per_line.expected")); +} + +#[test] +fn test_single_non_newline_separator() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-s", ":", "delimited_primes.txt"]).run(); + assert_eq!(result.stdout, at.read("delimited_primes.expected")); +} + +#[test] +fn test_single_non_newline_separator_before() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-b", "-s", ":", "delimited_primes.txt"]).run(); + assert_eq!(result.stdout, at.read("delimited_primes_before.expected")); +} diff --git a/tests/test.rs b/tests/test.rs new file mode 100644 index 000000000..842018f32 --- /dev/null +++ b/tests/test.rs @@ -0,0 +1,56 @@ +#[macro_use] +mod common; + +// +// This file is part of the uutils coreutils package. +// +// (c) mahkoh (ju.orth [at] gmail [dot] com) +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. +// + +use common::util::*; + +static UTIL_NAME: &'static str = "test"; + + +#[test] +fn test_op_prec_and_or_1() { + let (_, mut ucmd) = testing(UTIL_NAME); + let exit_success = ucmd.arg(" ") + .arg("-o") + .arg("") + .arg("-a") + .arg("") + .run() + .success; + assert!(exit_success); +} + +#[test] +fn test_op_prec_and_or_2() { + let (_, mut ucmd) = testing(UTIL_NAME); + let exit_success = ucmd.arg("") + .arg("-a") + .arg("") + .arg("-o") + .arg(" ") + .arg("-a") + .arg(" ") + .run() + .success; + assert!(exit_success); +} + +#[test] +fn test_or_as_filename() { + let (_, mut ucmd) = testing(UTIL_NAME); + let exit_success = ucmd.arg("x") + .arg("-a") + .arg("-z") + .arg("-o") + .run() + .success; + assert!(!exit_success); +} diff --git a/test/touch.rs b/tests/touch.rs similarity index 54% rename from test/touch.rs rename to tests/touch.rs index 642844f18..ce95ca286 100644 --- a/test/touch.rs +++ b/tests/touch.rs @@ -1,26 +1,22 @@ -extern crate libc; +#[macro_use] +mod common; + extern crate time; -extern crate kernel32; -extern crate winapi; extern crate filetime; use filetime::FileTime; -use std::process::Command; -use util::*; +use common::util::*; -static PROGNAME: &'static str = "./touch"; +static UTIL_NAME: &'static str = "touch"; -#[path = "common/util.rs"] -#[macro_use] -mod util; - -fn get_file_times(path: &str) -> (FileTime, FileTime) { - let m = metadata(path); - (FileTime::from_last_access_time(&m), FileTime::from_last_modification_time(&m)) +fn get_file_times(at: &AtPath, path: &str) -> (FileTime, FileTime) { + let m = at.metadata(path); + (FileTime::from_last_access_time(&m), + FileTime::from_last_modification_time(&m)) } -fn set_file_times(path: &str, atime: FileTime, mtime: FileTime) { - filetime::set_file_times(path, atime, mtime).unwrap() +fn set_file_times(at: &AtPath, path: &str, atime: FileTime, mtime: FileTime) { + filetime::set_file_times(&at.plus_as_string(path), atime, mtime).unwrap() } // Adjusts for local timezone @@ -33,208 +29,237 @@ fn str_to_filetime(format: &str, s: &str) -> FileTime { #[test] fn test_touch_default() { + let (at, mut ucmd) = testing(UTIL_NAME); let file = "test_touch_default_file"; - let result = run(Command::new(PROGNAME).arg(file)); + let result = ucmd.arg(file).run(); assert_empty_stderr!(result); assert!(result.success); - assert!(file_exists(file)); + assert!(at.file_exists(file)); } #[test] fn test_touch_no_create_file_absent() { + let (at, mut ucmd) = testing(UTIL_NAME); let file = "test_touch_no_create_file_absent"; - let result = run(Command::new(PROGNAME).arg("-c").arg(file)); + let result = ucmd.arg("-c").arg(file).run(); assert_empty_stderr!(result); assert!(result.success); - assert!(!file_exists(file)); + assert!(!at.file_exists(file)); } #[test] fn test_touch_no_create_file_exists() { + let (at, mut ucmd) = testing(UTIL_NAME); let file = "test_touch_no_create_file_exists"; - touch(file); - assert!(file_exists(file)); + at.touch(file); + assert!(at.file_exists(file)); - let result = run(Command::new(PROGNAME).arg("-c").arg(file)); + let result = ucmd.arg("-c").arg(file).run(); assert_empty_stderr!(result); assert!(result.success); - assert!(file_exists(file)); + assert!(at.file_exists(file)); } #[test] fn test_touch_set_mdhm_time() { + let (at, mut ucmd) = testing(UTIL_NAME); let file = "test_touch_set_mdhm_time"; - let result = run(Command::new(PROGNAME).args(&["-t", "01011234", file])); + let result = ucmd.args(&["-t", "01011234", file]).run(); assert_empty_stderr!(result); assert!(result.success); - assert!(file_exists(file)); + assert!(at.file_exists(file)); let start_of_year = str_to_filetime("%Y%m%d%H%M", "201501010000"); - let (atime, mtime) = get_file_times(file); + let (atime, mtime) = get_file_times(&at, file); assert_eq!(atime, mtime); - assert_eq!(atime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), 45240); - assert_eq!(mtime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), 45240); + assert_eq!(atime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), + 45240); + assert_eq!(mtime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), + 45240); } #[test] fn test_touch_set_mdhms_time() { + let (at, mut ucmd) = testing(UTIL_NAME); let file = "test_touch_set_mdhms_time"; - let result = run(Command::new(PROGNAME).args(&["-t", "01011234.56", file])); + let result = ucmd.args(&["-t", "01011234.56", file]).run(); assert_empty_stderr!(result); assert!(result.success); - assert!(file_exists(file)); + assert!(at.file_exists(file)); let start_of_year = str_to_filetime("%Y%m%d%H%M.%S", "201501010000.00"); - let (atime, mtime) = get_file_times(file); + let (atime, mtime) = get_file_times(&at, file); assert_eq!(atime, mtime); - assert_eq!(atime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), 45296); - assert_eq!(mtime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), 45296); + assert_eq!(atime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), + 45296); + assert_eq!(mtime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), + 45296); } #[test] fn test_touch_set_ymdhm_time() { + let (at, mut ucmd) = testing(UTIL_NAME); let file = "test_touch_set_ymdhm_time"; - let result = run(Command::new(PROGNAME).args(&["-t", "1501011234", file])); + let result = ucmd.args(&["-t", "1501011234", file]).run(); assert_empty_stderr!(result); assert!(result.success); - assert!(file_exists(file)); + assert!(at.file_exists(file)); let start_of_year = str_to_filetime("%y%m%d%H%M", "1501010000"); - let (atime, mtime) = get_file_times(file); + let (atime, mtime) = get_file_times(&at, file); assert_eq!(atime, mtime); - assert_eq!(atime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), 45240); - assert_eq!(mtime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), 45240); + assert_eq!(atime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), + 45240); + assert_eq!(mtime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), + 45240); } #[test] fn test_touch_set_ymdhms_time() { + let (at, mut ucmd) = testing(UTIL_NAME); let file = "test_touch_set_ymdhms_time"; - let result = run(Command::new(PROGNAME).args(&["-t", "1501011234.56", file])); + let result = ucmd.args(&["-t", "1501011234.56", file]).run(); assert_empty_stderr!(result); assert!(result.success); - assert!(file_exists(file)); + assert!(at.file_exists(file)); let start_of_year = str_to_filetime("%y%m%d%H%M.%S", "1501010000.00"); - let (atime, mtime) = get_file_times(file); + let (atime, mtime) = get_file_times(&at, file); assert_eq!(atime, mtime); - assert_eq!(atime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), 45296); - assert_eq!(mtime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), 45296); + assert_eq!(atime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), + 45296); + assert_eq!(mtime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), + 45296); } #[test] fn test_touch_set_cymdhm_time() { + let (at, mut ucmd) = testing(UTIL_NAME); let file = "test_touch_set_cymdhm_time"; - let result = run(Command::new(PROGNAME).args(&["-t", "201501011234", file])); + let result = ucmd.args(&["-t", "201501011234", file]).run(); assert_empty_stderr!(result); assert!(result.success); - assert!(file_exists(file)); + assert!(at.file_exists(file)); let start_of_year = str_to_filetime("%Y%m%d%H%M", "201501010000"); - let (atime, mtime) = get_file_times(file); + let (atime, mtime) = get_file_times(&at, file); assert_eq!(atime, mtime); - assert_eq!(atime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), 45240); - assert_eq!(mtime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), 45240); + assert_eq!(atime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), + 45240); + assert_eq!(mtime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), + 45240); } #[test] fn test_touch_set_cymdhms_time() { + let (at, mut ucmd) = testing(UTIL_NAME); let file = "test_touch_set_cymdhms_time"; - let result = run(Command::new(PROGNAME).args(&["-t", "201501011234.56", file])); + let result = ucmd.args(&["-t", "201501011234.56", file]).run(); assert_empty_stderr!(result); assert!(result.success); - assert!(file_exists(file)); + assert!(at.file_exists(file)); let start_of_year = str_to_filetime("%Y%m%d%H%M.%S", "201501010000.00"); - let (atime, mtime) = get_file_times(file); + let (atime, mtime) = get_file_times(&at, file); assert_eq!(atime, mtime); - assert_eq!(atime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), 45296); - assert_eq!(mtime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), 45296); + assert_eq!(atime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), + 45296); + assert_eq!(mtime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), + 45296); } #[test] fn test_touch_set_only_atime() { + let (at, mut ucmd) = testing(UTIL_NAME); let file = "test_touch_set_only_atime"; - let result = run(Command::new(PROGNAME).args(&["-t", "201501011234", "-a", file])); + let result = ucmd.args(&["-t", "201501011234", "-a", file]).run(); assert_empty_stderr!(result); assert!(result.success); - assert!(file_exists(file)); + assert!(at.file_exists(file)); let start_of_year = str_to_filetime("%Y%m%d%H%M", "201501010000"); - let (atime, mtime) = get_file_times(file); + let (atime, mtime) = get_file_times(&at, file); assert!(atime != mtime); - assert_eq!(atime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), 45240); + assert_eq!(atime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), + 45240); } #[test] fn test_touch_set_only_mtime() { + let (at, mut ucmd) = testing(UTIL_NAME); let file = "test_touch_set_only_mtime"; - let result = run(Command::new(PROGNAME).args(&["-t", "201501011234", "-m", file])); + let result = ucmd.args(&["-t", "201501011234", "-m", file]).run(); assert_empty_stderr!(result); assert!(result.success); - assert!(file_exists(file)); + assert!(at.file_exists(file)); let start_of_year = str_to_filetime("%Y%m%d%H%M", "201501010000"); - let (atime, mtime) = get_file_times(file); + let (atime, mtime) = get_file_times(&at, file); assert!(atime != mtime); - assert_eq!(mtime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), 45240); + assert_eq!(mtime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), + 45240); } #[test] fn test_touch_set_both() { + let (at, mut ucmd) = testing(UTIL_NAME); let file = "test_touch_set_both"; - let result = run(Command::new(PROGNAME).args(&["-t", "201501011234", "-a", "-m", file])); + let result = ucmd.args(&["-t", "201501011234", "-a", "-m", file]).run(); assert_empty_stderr!(result); assert!(result.success); - assert!(file_exists(file)); + assert!(at.file_exists(file)); let start_of_year = str_to_filetime("%Y%m%d%H%M", "201501010000"); - let (atime, mtime) = get_file_times(file); + let (atime, mtime) = get_file_times(&at, file); assert_eq!(atime, mtime); - assert_eq!(atime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), 45240); - assert_eq!(mtime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), 45240); + assert_eq!(atime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), + 45240); + assert_eq!(mtime.seconds_relative_to_1970() - start_of_year.seconds_relative_to_1970(), + 45240); } #[test] fn test_touch_reference() { + let (at, mut ucmd) = testing(UTIL_NAME); let file_a = "test_touch_reference_a"; let file_b = "test_touch_reference_b"; let start_of_year = str_to_filetime("%Y%m%d%H%M", "201501010000"); - touch(file_a); - set_file_times(file_a, start_of_year, start_of_year); - assert!(file_exists(file_a)); + at.touch(file_a); + set_file_times(&at, file_a, start_of_year, start_of_year); + assert!(at.file_exists(file_a)); - let result = run(Command::new(PROGNAME).args(&["-r", file_a, file_b])); + let result = ucmd.args(&["-r", file_a, file_b]).run(); assert_empty_stderr!(result); assert!(result.success); - assert!(file_exists(file_b)); + assert!(at.file_exists(file_b)); - let (atime, mtime) = get_file_times(file_b); + let (atime, mtime) = get_file_times(&at, file_b); assert_eq!(atime, mtime); assert_eq!(atime, start_of_year); assert_eq!(mtime, start_of_year); @@ -242,16 +267,17 @@ fn test_touch_reference() { #[test] fn test_touch_set_date() { + let (at, mut ucmd) = testing(UTIL_NAME); let file = "test_touch_set_date"; - let result = run(Command::new(PROGNAME).args(&["-d", "Thu Jan 01 12:34:00 2015", file])); + let result = ucmd.args(&["-d", "Thu Jan 01 12:34:00 2015", file]).run(); assert_empty_stderr!(result); assert!(result.success); - assert!(file_exists(file)); + assert!(at.file_exists(file)); let start_of_year = str_to_filetime("%Y%m%d%H%M", "201501011234"); - let (atime, mtime) = get_file_times(file); + let (atime, mtime) = get_file_times(&at, file); assert_eq!(atime, mtime); assert_eq!(atime, start_of_year); assert_eq!(mtime, start_of_year); diff --git a/tests/tr.rs b/tests/tr.rs new file mode 100644 index 000000000..869a3c51c --- /dev/null +++ b/tests/tr.rs @@ -0,0 +1,44 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "tr"; + + + +#[test] +fn test_toupper() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["a-z", "A-Z"]).run_piped_stdin(b"!abcd!"); + assert_eq!(result.stdout, "!ABCD!"); +} + +#[test] +fn test_small_set2() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["0-9", "X"]).run_piped_stdin(b"@0123456789"); + assert_eq!(result.stdout, "@XXXXXXXXXX"); +} + +#[test] +fn test_unicode() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&[", ┬─┬", "╯︵┻━┻"]) + .run_piped_stdin("(,°□°), ┬─┬".as_bytes()); + assert_eq!(result.stdout, "(╯°□°)╯︵┻━┻"); +} + +#[test] +fn test_delete() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-d", "a-z"]).run_piped_stdin(b"aBcD"); + assert_eq!(result.stdout, "BD"); +} + +#[test] +fn test_delete_complement() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-d", "-c", "a-z"]).run_piped_stdin(b"aBcD"); + assert_eq!(result.stdout, "ac"); +} diff --git a/tests/true.rs b/tests/true.rs new file mode 100644 index 000000000..f50e77a78 --- /dev/null +++ b/tests/true.rs @@ -0,0 +1,13 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "true"; + +#[test] +fn test_exit_code() { + let (_, mut ucmd) = testing(UTIL_NAME); + let exit_status = ucmd.run().success; + assert_eq!(exit_status, true); +} diff --git a/tests/truncate.rs b/tests/truncate.rs new file mode 100644 index 000000000..d1406a979 --- /dev/null +++ b/tests/truncate.rs @@ -0,0 +1,30 @@ +#[macro_use] +mod common; + +use std::io::{Seek, SeekFrom, Write}; +use common::util::*; + +static UTIL_NAME: &'static str = "truncate"; + +static TFILE1: &'static str = "truncate_test_1"; +static TFILE2: &'static str = "truncate_test_2"; + +#[test] +fn test_increase_file_size() { + let (at, mut ucmd) = testing(UTIL_NAME); + let mut file = at.make_file(TFILE1); + assert!(ucmd.args(&["-s", "+5K", TFILE1]).run().success); + + file.seek(SeekFrom::End(0)).unwrap(); + assert!(file.seek(SeekFrom::Current(0)).unwrap() == 5 * 1024); +} + +#[test] +fn test_decrease_file_size() { + let (at, mut ucmd) = testing(UTIL_NAME); + let mut file = at.make_file(TFILE2); + file.write_all(b"1234567890").unwrap(); + assert!(ucmd.args(&["--size=-4", TFILE2]).run().success); + file.seek(SeekFrom::End(0)).unwrap(); + assert!(file.seek(SeekFrom::Current(0)).unwrap() == 6); +} diff --git a/tests/tsort.rs b/tests/tsort.rs new file mode 100644 index 000000000..4bc388c44 --- /dev/null +++ b/tests/tsort.rs @@ -0,0 +1,20 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "tsort"; + +#[test] +fn test_sort_call_graph() { + let (at, mut ucmd) = testing(UTIL_NAME); + let input = "call_graph.txt"; + let output = "call_graph.expected"; + + let out = ucmd.arg(input) + .run() + .stdout; + + assert_eq!(out, + String::from_utf8(at.read(output).into_bytes()).unwrap()); +} diff --git a/tests/unexpand.rs b/tests/unexpand.rs new file mode 100644 index 000000000..d51da4e98 --- /dev/null +++ b/tests/unexpand.rs @@ -0,0 +1,116 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "unexpand"; + +#[test] +fn unexpand_init_0() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-t4"]).run_piped_stdin(" 1\n 2\n 3\n 4\n"); + assert_eq!(result.stdout, " 1\n 2\n 3\n\t4\n"); +} + +#[test] +fn unexpand_init_1() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-t4"]).run_piped_stdin(" 5\n 6\n 7\n 8\n"); + assert_eq!(result.stdout, "\t 5\n\t 6\n\t 7\n\t\t8\n"); +} + +#[test] +fn unexpand_init_list_0() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-t2,4"]).run_piped_stdin(" 1\n 2\n 3\n 4\n"); + assert_eq!(result.stdout, " 1\n\t2\n\t 3\n\t\t4\n"); +} + +#[test] +fn unexpand_init_list_1() { + // Once the list is exhausted, spaces are not converted anymore + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-t2,4"]).run_piped_stdin(" 5\n 6\n 7\n 8\n"); + assert_eq!(result.stdout, "\t\t 5\n\t\t 6\n\t\t 7\n\t\t 8\n"); +} + +#[test] +fn unexpand_aflag_0() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["--"]).run_piped_stdin("e E\nf F\ng G\nh H\n"); + assert_eq!(result.stdout, "e E\nf F\ng G\nh H\n"); +} + +#[test] +fn unexpand_aflag_1() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-a"]).run_piped_stdin("e E\nf F\ng G\nh H\n"); + assert_eq!(result.stdout, "e E\nf F\ng\tG\nh\t H\n"); +} + +#[test] +fn unexpand_aflag_2() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-t8"]).run_piped_stdin("e E\nf F\ng G\nh H\n"); + assert_eq!(result.stdout, "e E\nf F\ng\tG\nh\t H\n"); +} + +#[test] +fn unexpand_first_only_0() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-t3"]).run_piped_stdin(" A B"); + assert_eq!(result.stdout, "\t\t A\t B"); +} + +#[test] +fn unexpand_first_only_1() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-t3", "--first-only"]).run_piped_stdin(" A B"); + assert_eq!(result.stdout, "\t\t A B"); +} + +#[test] +fn unexpand_trailing_space_0() { + // evil + // Individual spaces before fields starting with non blanks should not be + // converted, unless they are at the beginning of the line. + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-t4"]).run_piped_stdin("123 \t1\n123 1\n123 \n123 "); + assert_eq!(result.stdout, "123\t\t1\n123 1\n123 \n123 "); +} + +#[test] +fn unexpand_trailing_space_1() { + // super evil + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-t1"]).run_piped_stdin(" abc d e f g "); + assert_eq!(result.stdout, "\tabc d e\t\tf\t\tg "); +} + +#[test] +fn unexpand_spaces_follow_tabs_0() { + // The two first spaces can be included into the first tab. + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.run_piped_stdin(" \t\t A"); + assert_eq!(result.stdout, "\t\t A"); +} + +#[test] +fn unexpand_spaces_follow_tabs_1() { + // evil + // Explanation of what is going on here: + // 'a' -> 'a' // first tabstop (1) + // ' \t' -> '\t' // second tabstop (4) + // ' ' -> '\t' // third tabstop (5) + // ' B \t' -> ' B \t' // after the list is exhausted, nothing must change + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-t1,4,5"]).run_piped_stdin("a \t B \t"); + assert_eq!(result.stdout, "a\t\t B \t"); +} + +#[test] +fn unexpand_spaces_after_fields() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-a"]).run_piped_stdin(" \t A B C D A\t\n"); + assert_eq!(result.stdout, "\t\tA B C D\t\t A\t\n"); +} diff --git a/tests/unlink.rs b/tests/unlink.rs new file mode 100644 index 000000000..2cc080f4f --- /dev/null +++ b/tests/unlink.rs @@ -0,0 +1,63 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "unlink"; + + +#[test] +fn test_unlink_file() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file = "test_unlink_file"; + + at.touch(file); + + let result = ucmd.arg(file).run(); + assert_empty_stderr!(result); + assert!(result.success); + + assert!(!at.file_exists(file)); +} + +#[test] +fn test_unlink_multiple_files() { + let (at, mut ucmd) = testing(UTIL_NAME); + let file_a = "test_unlink_multiple_file_a"; + let file_b = "test_unlink_multiple_file_b"; + + at.touch(file_a); + at.touch(file_b); + + let result = ucmd.arg(file_a).arg(file_b).run(); + assert_eq!(result.stderr, + "unlink: error: extra operand: 'test_unlink_multiple_file_b'\nTry 'unlink --help' \ + for more information.\n"); + assert!(!result.success); +} + +#[test] +fn test_unlink_directory() { + let (at, mut ucmd) = testing(UTIL_NAME); + let dir = "test_unlink_empty_directory"; + + at.mkdir(dir); + + let result = ucmd.arg(dir).run(); + assert_eq!(result.stderr, + "unlink: error: cannot unlink 'test_unlink_empty_directory': Not a regular file \ + or symlink\n"); + assert!(!result.success); +} + +#[test] +fn test_unlink_nonexistent() { + let (_, mut ucmd) = testing(UTIL_NAME); + let file = "test_unlink_nonexistent"; + + let result = ucmd.arg(file).run(); + assert_eq!(result.stderr, + "unlink: error: Cannot stat 'test_unlink_nonexistent': No such file or directory \ + (os error 2)\n"); + assert!(!result.success); +} diff --git a/tests/wc.rs b/tests/wc.rs new file mode 100644 index 000000000..a351ba0ce --- /dev/null +++ b/tests/wc.rs @@ -0,0 +1,59 @@ +#[macro_use] +mod common; + +use common::util::*; + +static UTIL_NAME: &'static str = "wc"; + +#[test] +fn test_stdin_default() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.run_piped_stdin(at.read("lorem_ipsum.txt")); + assert_eq!(result.stdout, " 13 109 772\n"); +} + +#[test] +fn test_stdin_only_bytes() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-c"]).run_piped_stdin(at.read("lorem_ipsum.txt")); + assert_eq!(result.stdout, " 772\n"); +} + +#[test] +fn test_stdin_all_counts() { + let (at, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-c", "-m", "-l", "-L", "-w"]) + .run_piped_stdin(at.read("alice_in_wonderland.txt")); + assert_eq!(result.stdout, " 5 57 302 302 66\n"); +} + +#[test] +fn test_single_default() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.arg("moby_dick.txt").run(); + assert_eq!(result.stdout, " 18 204 1115 moby_dick.txt\n"); +} + +#[test] +fn test_single_only_lines() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-l", "moby_dick.txt"]).run(); + assert_eq!(result.stdout, " 18 moby_dick.txt\n"); +} + +#[test] +fn test_single_all_counts() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["-c", "-l", "-L", "-m", "-w", "alice_in_wonderland.txt"]).run(); + assert_eq!(result.stdout, + " 5 57 302 302 66 alice_in_wonderland.txt\n"); +} + +#[test] +fn test_multiple_default() { + let (_, mut ucmd) = testing(UTIL_NAME); + let result = ucmd.args(&["lorem_ipsum.txt", "moby_dick.txt", "alice_in_wonderland.txt"]).run(); + assert_eq!(result.stdout, + " 13 109 772 lorem_ipsum.txt\n 18 204 1115 moby_dick.txt\n 5 57 302 \ + alice_in_wonderland.txt\n 36 370 2189 total\n"); +}