specify posix.compat: - describe chmod: - before: chmod, stat = posix.chmod, posix.stat touch "xxx" chmod ("xxx", "rwxr-x---") - after: os.remove "xxx" - context with bad arguments: | examples { ["it diagnoses argument #2 invalid mode"] = function () expect (chmod (".", "g+vv")).to_raise.any_of { "bad argument #2 to '?' (bad mode)", "bad argument #2 to 'chmod' (bad mode)", } end } badargs.diagnose (chmod, "chmod (string, string)") - it sets file mode with longhand mode string: mode = "rw---xr--" expect (Emsg (chmod ("xxx", mode))).to_be "" expect (stat ("xxx", "mode")).to_be (mode) - "it sets attributes with '='": expect (Emsg (chmod ("xxx", "o=w"))).to_be "" expect (stat ("xxx", "mode")).to_be "rwxr-x-w-" - "it adds attributes with '+'": expect (Emsg (chmod ("xxx", "g+w"))).to_be "" expect (stat ("xxx", "mode")).to_be "rwxrwx---" - "it removes attributes with '-'": expect (Emsg (chmod ("xxx", "u-r"))).to_be "" expect (stat ("xxx", "mode")).to_be "-wxr-x---" - it accepts comma separated attribute specifications: expect (Emsg (chmod ("xxx", "a+x,g+w,u-w"))).to_be "" expect (stat ("xxx", "mode")).to_be "r-xrwx--x" - it diagnoses missing files: os.remove "xxx" expect (Emsg (chmod ("xxx", "a=rwx"))).to_contain "No such file or directory" - describe clock_getres: - before: clock_getres = posix.clock_getres - context with bad arguments: if clock_getres then badargs.diagnose (clock_getres, "clock_getres (?string)") end - describe clock_gettime: - before: clock_gettime = posix.clock_gettime - context with bad arguments: if clock_gettime then badargs.diagnose (clock_gettime, "clock_gettime (?string)") end - describe creat: - before: creat = posix.creat - context with bad arguments: | badargs.diagnose (creat, "creat (string, string)") examples { ["it diagnoses argument #2 invalid mode"] = function () expect (creat ("not/existing", "g+vv")).to_raise.any_of { "bad argument #2 to '?' (bad mode)", "bad argument #2 to 'creat' (bad mode)", } end } - describe fadvise: - context with bad arguments: if posix.fadvise then badargs.diagnose (posix.fadvise, "fadvise (file, int, int, int)") end - describe fnmatch: - before: fnmatch, FNM_PATHNAME, FNM_PERIOD = posix.fnmatch, posix.FNM_PATHNAME, posix.FNM_PERIOD - context with bad arguments: badargs.diagnose (fnmatch, "fnmatch (string, string, ?int)") - it matches a file path against itself: expect (fnmatch ("test", "test")).to_be (true) - "it matches * against any filename characters": expect (fnmatch ("tes*", "test")).to_be (true) expect (fnmatch ("tes*", "test2")).to_be (true) expect (fnmatch ("*t*", "test")).to_be (true) - "it matches ? against a single filename character": expect (fnmatch ("tes?", "test")).to_be (true) expect (fnmatch ("t???", "test")).to_be (true) expect (fnmatch ("tes?", "tes")).to_be (false) expect (fnmatch ("tes?", "test2")).to_be (false) - "it doesn't match path separators with FNM_PATHNAME": expect (fnmatch ("*test", "/test")).to_be (true) expect (fnmatch ("*test", "/test", FNM_PATHNAME)).to_be (false) - "it doesn't match periods with FNM_PERIOD": expect (fnmatch ("*test", ".test")).to_be (true) expect (fnmatch ("*test", ".test", FNM_PERIOD)).to_be (false) - describe getgroup: - before: getgrgid, getgroup, getegid = posix.getgrgid, posix.getgroup, posix.getegid groot = getgrgid (0).gr_name - context with bad arguments: badargs.diagnose (posix.getgroup, "getgroup (?string|int)") - it returns a table for an existing group: expect (type (getgroup (groot))).to_be "table" - it fetches current group by default: expect (getgroup ()).to_equal (getgroup (getegid ())) - it fetches a group by gid: expect (getgroup (0).name).to_be (groot) expect (getgroup (0).gid).to_be (0) expect (type (getgroup (0).mem)).to_be "table" - it fetches a group by name: expect (getgroup (groot).name).to_be (groot) expect (getgroup (groot).gid).to_be (0) expect (type (getgroup (groot).mem)).to_be "table" - describe getpasswd: - before: getenv, getgid, getpasswd, getuid = posix.getenv, posix.getgid, posix.getpasswd, posix.getuid user = getpasswd ((getenv "USER"), "name") root = getpasswd (0, "name") - context with bad arguments: - before: getpasswd, typeerrors = init (posix, "getpasswd") - 'it diagnoses argument #1 type not string, int or nil': expect (getpasswd (false)). to_raise.any_of (typeerrors (1, "?string|int", "boolean")) - it fetches the user uid: expect (getpasswd (user).uid).to_be (getuid ()) expect (getpasswd (root, "uid")).to_be (0) - it fetches the user name: expect (getpasswd (user).name).to_be (user) expect (getpasswd (0, "name")).to_be (root) expect (getpasswd (root, "name")).to_be (root) - it fetches the user gid: expect (getpasswd (user).gid).to_be (getgid ()) expect (getpasswd (0, "gid")).to_be (0) expect (getpasswd (root, "gid")).to_be (0) - it fetches the user password: expect (getpasswd (user).passwd).to_match.any_of {"x", "%*+"} expect (getpasswd (0, "passwd")).to_match.any_of {"x", "%*+"} expect (getpasswd (root, "passwd")).to_match.any_of {"x", "%*+"} - it fetches the user home directory: expect (getpasswd (user, "dir")).to_be (getenv "HOME") - it fetches the user shell: expect (getpasswd (user, "shell")).to_be (getenv "SHELL") - it fetches a subtable of named fields: expect ({getpasswd (user, "name", "shell", "dir")}). to_equal {user, getenv "SHELL", getenv "HOME"} - it fetches everything without an argument: t = getpasswd (user) for k, v in pairs (t) do expect (t[k]).to_be (getpasswd (user, k)) end - describe getpid: - before: getpid, typeerrors = init (posix, "getpid") # posix.getpid takes an optional string or table as its first # argument, followed by zero or more strings only if the first # argument was a string; since we can't express that with # `badargs.diagnose` do it all manually again... - context with bad arguments: - 'it diagnoses argument #1 type not table, string or nil': expect (getpid (false)).to_raise. any_of (typeerrors (1, "?table|string", "boolean")) - 'it diagnoses argument #1 string invalid': | expect (getpid ("fubar")).to_raise.any_of { "bad argument #1 to '?' (invalid option 'fubar')", "bad argument #1 to 'getpid' (invalid option 'fubar')", } - 'it diagnoses argument #2 type not string': expect (getpid ("ppid", false)). to_raise.any_of (typeerrors (2, "string", "boolean")) - it diagnoses too many arguments: expect (getpid ({}, false)).to_raise.any_of (typeerrors (2)) - describe getrlimit: - before: getrlimit = posix.getrlimit - context with bad arguments: | examples { ["it diagnoses argument #1 invalid option"] = function () expect (getrlimit ("fubar")).to_raise.any_of { "bad argument #1 to '?' (invalid option 'fubar')", "bad argument #1 to 'getrlimit' (invalid option 'fubar')", } end } badargs.diagnose (getrlimit, "getrlimit (string)") - it fetches resource limits for a process: for _, rc in pairs {"core", "cpu", "data", "fsize", "nofile", "stack", "as"} do cur, max = getrlimit (rc) expect (type (cur)).to_be "number" expect (type (max)).to_be "number" end - describe gettimeofday: - before: gettimeofday = posix.gettimeofday - context with bad arguments: badargs.diagnose (gettimeofday, "gettimeofday ()") - it fetches the current epoch time: t, epoch = gettimeofday (), posix.time () expect (t.sec).to_be (epoch) expect (type (t.usec)).to_be "number" expect (t.usec >= 0).to_be (true) - describe gmtime: - before: gmtime = posix.gmtime - context with bad arguments: badargs.diagnose (gmtime, "gmtime (?int)") - it returns a table: expect (prototype (gmtime (now))).to_be "table" - it fetches broken-down time values: t = gmtime (now) fields = {"sec", "min", "hour", "day", "monthday", "month", "year", "weekday", "yearday", "is_dst"} expect (t).to_contain.a_permutation_of (fields) for _, field in pairs (fields) do if field == "is_dst" then expect (type (t.is_dst)).to_be "boolean" else expect (type (t[field])).to_be "number" expect (t[field] >= 0).to_be (true) end end - it returns a month in the range 1-12: # A recent December afternoon in epoch seconds... expect (gmtime (1418734089).month).to_be (12) t = gmtime (now) expect (t.month >= 1 and t.month <= 12).to_be (true) - it returns full year: expect (gmtime (now).year > 2000).to_be (true) - describe hostid: - context with bad arguments: badargs.diagnose (posix.hostid, "()") - describe isgraph: - before: isgraph = posix.isgraph - context with bad arguments: badargs.diagnose (isgraph, "isgraph (string)") - it returns true for successful tests: expect (isgraph 'a').to_be (true) - it returns false for failed tests: expect (isgraph ' ').to_be (false) - describe isprint: - before: isprint = posix.isprint - context with bad arguments: badargs.diagnose (isprint, "isprint (string)") - it returns true for successful tests: expect (isprint 'a').to_be (true) - it returns false for failed tests: expect (isprint (string.char (0))).to_be (false) - describe localtime: - before: localtime = posix.localtime - context with bad arguments: badargs.diagnose (localtime, "localtime (?int)") - it returns a table: expect (prototype (localtime (now))).to_be "table" - it fetches broken-down time values: t = localtime (now) fields = {"sec", "min", "hour", "day", "monthday", "month", "year", "weekday", "yearday", "is_dst"} expect (t).to_contain.a_permutation_of (fields) for _, field in pairs (fields) do if field == "is_dst" then expect (type (t.is_dst)).to_be "boolean" else expect (type (t[field])).to_be "number" expect (t[field] >= 0).to_be (true) end end - it returns a month in the range 1-12: # A recent December afternoon in epoch seconds... expect (localtime (1418734089).month).to_be (12) t = localtime (now) expect (t.month >= 1 and t.month <= 12).to_be (true) - it returns years since 1900: expect (localtime (now).year > 2000).to_be (true) - describe mkdir: - before: dir = posix.mkdtemp (template) chdir, mkdir = posix.chdir, posix.mkdir cwd = posix.getcwd () - after: chdir (cwd) rmtmp (dir) - context with bad arguments: badargs.diagnose (mkdir, "mkdir (string)") - it creates the named directory: expect (Emsg (mkdir (dir .. "/subdir"))).not_to_contain "exists" expect (Emsg (chdir (dir .. "/subdir"))).not_to_contain "No such flle or directory" - it diagnoses already existing directory: expect (Emsg (mkdir (dir))).to_contain "exists" - describe mkfifo: - before: dir = posix.mkdtemp (template) mkfifo = posix.mkfifo - after: rmtmp (dir) - context with bad arguments: badargs.diagnose (mkfifo, "mkfifo (string)") - it creates the named fifo: expect (Emsg (mkfifo (dir .. "/fifo"))).not_to_contain "exists" expect (posix.stat (dir .. "/fifo").type).to_be "fifo" - it diagnoses already existing fifo: expect (Emsg (mkfifo (dir))).to_contain "exists" - describe mktime: - before: localtime, mktime, time = posix.localtime, posix.mktime, posix.time epoch = time () t = localtime (epoch) - context with bad arguments: badargs.diagnose (mktime, "mktime (?table)") - it returns an epoch time: expect (prototype (mktime (t))).to_be "number" - it is the inverse of localtime: expect (mktime (t)).to_be (epoch) - it defaults to current time: | -- avoid a race by discarding the unit seconds expect (mktime () / 10).to_be (epoch / 10) - describe msgget: - before: msgget = posix.msgget EEXIST, IPC_CREAT, IPC_EXCL = posix.EEXIST, posix.IPC_CREAT, posix.IPC_EXCL - context with bad arguments: badargs.diagnose (msgget, "msgget (int, ?int, ?string)") - it creates a queue: if msgget then modestr = "rwxrwxrwx" mq, err, errnum = msgget (100, bor (IPC_CREAT, IPC_EXCL), modestr) if errnum == EEXIST then mq, err = msgget (100, 0, modestr) end expect (mq).not_to_be (nil) expect (err).to_be (nil) end - describe nanosleep: - context with bad arguments: badargs.diagnose (posix.nanosleep, "nanosleep (int, int)") - it returns an integer: expect (posix.nanosleep (0, 10)).to_be (0) - describe open: # posix.open ignores the mode argument if flags does not include # O_CREAT, which `badargs.diagnose` can't express; ergo manual # checks here... - before: O_CREAT = posix.O_CREAT open, typeerrors = init (posix, "open") - 'it diagnoses missing argument #1': expect (open ()).to_raise.any_of (typeerrors (1, "string")) - 'it diagnoses argument #1 type not string': expect (open (false)).to_raise.any_of (typeerrors (1, "string", "boolean")) - 'it diagnoses missing argument #2': expect (open ("not/existing")).to_raise.any_of (typeerrors (2, "int")) - 'it diagnoses argument #2 type not int': expect (open ("not/existing", false)). to_raise.any_of (typeerrors (2, "int", "boolean")) - 'it diagnoses missing argument #3': expect (open ("not/existing", O_CREAT)). to_raise.any_of (typeerrors (3, "string")) - 'it diagnoses argument #3 type not string': expect (open ("not/existing", O_CREAT, false)). to_raise.any_of (typeerrors (3, "string", "boolean")) - 'it diagnoses argument #3 invalid mode': | expect (open ("not/existing", O_CREAT, "g+vv")).to_raise.any_of { "bad argument #3 to '?' (bad mode)", "bad argument #3 to 'open' (bad mode)", } - 'it diagnoses too many arguments': expect (open ("not/existing", -1, "o-s", false)).to_raise.any_of (typeerrors (4)) - describe pathconf: - before: pathconf, typeerrors = init (posix, "pathconf") # posix.pathconf takes an optional string or table as its second # argument, followed by zero or more strings only if the second # argument was a string; since we can't express that with # `badargs.diagnose` do it all manually again... - context with bad arguments: - 'it diagnoses argument #1 type not string': expect (pathconf (false)). to_raise.any_of (typeerrors (1, "?string", "boolean")) - 'it diagnoses argument #2 type not table, string or nil': expect (pathconf (".", false)). to_raise.any_of (typeerrors (2, "?table|string", "boolean")) - 'it diagnoses argument #2 string invalid': | expect (pathconf (".", "fubar")).to_raise.any_of { "bad argument #2 to '?' (invalid option 'fubar')", "bad argument #2 to 'pathconf' (invalid option 'fubar')", } - 'it diagnoses argument #3 type not string': expect (pathconf (".", "NAME_MAX", false)). to_raise.any_of (typeerrors (3, "string", "boolean")) - it diagnoses too many arguments: expect (pathconf (".", {}, false)).to_raise.any_of (typeerrors (3)) - it returns whether chown can be used on the given file: expect (type (pathconf ().CHOWN_RESTRICTED)).to_be "number" expect (pathconf (".", "CHOWN_RESTRICTED") >= 0).to_be (true) - it fetches the maximum number of links to the given file: expect (type (pathconf ().LINK_MAX)).to_be "number" expect (pathconf (".", "LINK_MAX") >= 0).to_be (true) - it fetches the maximum formatted line input length for a tty: | -- not passing a tty, so should return -1 expect (type (pathconf ().MAX_CANON)).to_be "number" pending "issue #102" expect (pathconf (".", "MAX_CANON")).to_be (-1) - it fetches the maximum raw line input length for a tty: | -- not passing a tty, so should return -1 expect (type (pathconf ().MAX_INPUT)).to_be "number" pending "issue #102" expect (pathconf (".", "MAX_INPUT")).to_be (-1) - it fetches the maximum filename length in this directory: expect (type (pathconf ().NAME_MAX)).to_be "number" expect (pathconf (".", "NAME_MAX") >= 0).to_be (true) - it fetches whether accessing overlong filenames is an error: expect (type (pathconf ().NO_TRUNC)).to_be "number" expect (pathconf (".", "NO_TRUNC") >= 0).to_be (true) - it fetches the maximum relative path length from this directory: expect (type (pathconf ().PATH_MAX)).to_be "number" expect (pathconf (".", "PATH_MAX") >= 0).to_be (true) - it fetches the size of the pipe buffer: expect (type (pathconf ().PIPE_BUF)).to_be "number" expect (pathconf (".", "PIPE_BUF") >= 0).to_be (true) - it fetches whether special character processing can be disabled: | -- not passing a tty, so should return -1 expect (type (pathconf ().VDISABLE)).to_be "number" pending "issue #102" expect (pathconf (".", "VDISABLE")).to_be (-1) - it fetches a subtable of named fields: expect ({pathconf (".", "VDISABLE", "NAME_MAX")}). to_equal {pathconf (".", "VDISABLE"), pathconf (".", "NAME_MAX")} - it fetches everything without an argument: t = pathconf () for k, v in pairs (t) do expect (t[k]).to_be (pathconf (".", k)) end - describe setrlimit: - before: setrlimit = posix.setrlimit - context with bad arguments: | examples { ["it diagnoses argument #1 invalid option"] = function () expect (setrlimit ("fubar")).to_raise.any_of { "bad argument #1 to '?' (invalid option 'fubar')", "bad argument #1 to 'setrlimit' (invalid option 'fubar')", } end } badargs.diagnose (setrlimit, "setrlimit (string, ?int, ?int)") - describe stat: - before: # choose a format without seconds, that won't cause a race condition fmt = "%b %d %H:%M" getegid, geteuid = posix.getegid, posix.geteuid stat, typeerrors = init (posix, "stat") dir = posix.mkdtemp (template) posix.mkdir (dir .. "/subdir") posix.link ("subdir", dir .. "/soft", true) touch (dir .. "/file") posix.link (dir .. "/file", dir .. "/hard") posix.link ("no such destination", dir .. "/dangling", true) posix.mkfifo (dir .. "/fifo") - after: rmtmp (dir) # posix.stat takes an optional string or table as its second # argument, followed by zero or more strings only if the second # argument was a string; since we can't express that with # `badargs.diagnose` do it all manually again... - context with bad arguments: - 'it diagnoses missing argument #1': expect (stat ()).to_raise.any_of (typeerrors (1, "string")) - 'it diagnoses argument #1 type not string': expect (stat (false)). to_raise.any_of (typeerrors (1, "string", "boolean")) - 'it diagnoses argument #2 type not table, string or nil': expect (stat (".", false)). to_raise.any_of (typeerrors (2, "?table|string", "boolean")) - 'it diagnoses argument #2 string invalid': | expect (stat (".", "fubar")).to_raise.any_of { "bad argument #2 to '?' (invalid option 'fubar')", "bad argument #2 to 'stat' (invalid option 'fubar')", } - 'it diagnoses argument #3 type not string': expect (stat (".", "type", false)). to_raise.any_of (typeerrors (3, "string", "boolean")) - it diagnoses too many arguments: expect (stat (".", {}, false)). to_raise.any_of (typeerrors (3)) - it fetches the file inode: expect (stat (dir .. "/hard").ino).to_be (stat (dir .. "/file").ino) - it fetches the file type: expect (stat (dir).type).to_be "directory" expect (stat (dir .. "/file", "type")).to_be "regular" expect (stat (dir .. "/soft", "type")).to_be "link" expect (stat (dir .. "/hard", "type")).to_be "regular" - it fetches the file size: # skip directory size, which is system dependent expect (stat (dir .. "/file").size).to_be (0) expect (stat (dir .. "/soft", "size")).to_be (string.len ("subdir")) expect (stat (dir .. "/hard", "size")). to_be (stat (dir .. "/file", "size")) - it fetches the file access time: expect (os.date (fmt, stat (dir .. "/file", "atime"))). to_be (os.date (fmt)) - it fetches the file modification time: expect (os.date (fmt, stat (dir .. "/file", "mtime"))). to_be (os.date (fmt)) - it fetches the file creation time: expect (os.date (fmt, stat (dir .. "/file", "ctime"))). to_be (os.date (fmt)) - it fetches the file access mode: expect (stat (dir .. "/file").mode).to_match ("^[-rwx]+$") expect (stat (dir .. "/subdir", "mode")).to_match ("^[-rwx]+$") - it fetches the number of links: expect (stat (dir .. "/file").nlink).to_be (2) expect (stat (dir .. "/soft", "nlink")).to_be (1) expect (stat (dir .. "/hard", "nlink")). to_be (stat (dir .. "/file", "nlink")) expect (stat (dir .. "/subdir", "nlink")).to_be (2) - it fetches the owner id: expect (stat (dir .. "/file").uid).to_be (geteuid ()) expect (stat (dir .. "/subdir", "uid")).to_be (geteuid ()) - it fetches the owner group id: expect (stat (dir .. "/file").gid).to_be (getegid ()) expect (stat (dir .. "/subdir", "gid")).to_be (getegid ()) - it fetches a subtable of named fields: expect ({stat (dir .. "/file", "type", "size", "nlink")}). to_equal {"regular", 0, 2} - it fetches everything without an argument: t = stat (dir .. "/file") for k, v in pairs (t) do expect (t[k]).to_be (stat (dir .. "/file", k)) end - describe statvfs: - before: statvfs, typeerrors = init (posix, "statvfs") # posix.statvfs takes an optional string or table as its second # argument, followed by zero or more strings only if the second # argument was a string; since we can't express that with # `badargs.diagnose` do it all manually again... - context with bad arguments: | if statvfs then examples { ["it diagnoses missing argument #1"] = function () expect (statvfs ()).to_raise.any_of (typeerrors (1, "string")) end } examples { ["it diagnoses argument #1 type not string"] = function () expect (statvfs (false)). to_raise.any_of (typeerrors (1, "string", "boolean")) end } examples { ["it diagnoses argument #2 type not table, string or nil"] = function () expect (statvfs (".", false)). to_raise.any_of (typeerrors (2, "?table|string", "boolean")) end } examples { ["it diagnoses argument #2 string invalid"] = function () expect (statvfs (".", "fubar")).to_raise.any_of { "bad argument #2 to '?' (invalid option 'fubar')", "bad argument #2 to 'statvfs' (invalid option 'fubar')", } end } examples { ["it diagnoses argument #3 type not string"] = function () expect (statvfs (".", "files", false)). to_raise.any_of (typeerrors (3, "string", "boolean")) end } examples { ["it diagnoses too many arguments"] = function () expect (statvfs (".", {}, false)).to_raise.any_of (typeerrors (3)) end } end - it fetches statistics for a mounted file system: if statvfs then sv = statvfs "/" expect (type (sv)).to_be "table" expect (sv.bsize).to_be (statvfs ("/", "bsize")) for _, field in pairs {"bsize", "frsize", "blocks", "bfree", "bavail", "files", "ffree", "favail", "flag", "namemax"} do expect (type (sv[field])).to_be "number" expect (sv[field] >= 0).to_be (true) end end - it returns a non-negative value from fsid: | -- Merge this back into the previous example when #102 is fixed if statvfs then sv = statvfs "/" pending "issue #102" expect (sv[field] >= 0).to_be (true) end - describe strftime: - before: strftime = posix.strftime t = { is_dst = true, weekday = 0, sec = 2, min = 3, hour = 4, monthday = 5, month = 6, year = 7, yearday = 8 } - context with bad arguments: badargs.diagnose (strftime, "strftime (string, ?table)") - context with place-holders: - it plugs weekday: expect (strftime ("%w", t)).to_be "0" - it plugs sec: expect (strftime ("%S", t)).to_be "02" - it plugs min: expect (strftime ("%M", t)).to_be "03" - it plugs hour: expect (strftime ("%H", t)).to_be "04" - it plugs monthday: expect (strftime ("%d", t)).to_be "05" - it plugs month: expect (strftime ("%m", t)).to_be "06" - it plugs year: expect (strftime ("%y", t)).to_be "07" - it plugs yearday: expect (strftime ("%j", t)).to_be "009" - it defaults to current time: expect (strftime "%Y-%m-%d\n"). to_be (io.popen ("date +'%Y-%m-%d'", "r"):read "*a") - describe strptime: - before: strptime = posix.strptime - context with bad arguments: badargs.diagnose (strptime, "strptime (string, string)") - context with place-holders: - before: t, i = strptime ("Mon Jun 4 03:02:01 BST 1906 garbage", "%a %b %d %H:%M:%S BST %Y") - it returns the first unconsumed character: expect (i).to_be (29) # tm_yday and tm_isdst are not set by strptime - it scans into weekday: expect (t.weekday).to_be (1) - it scans into sec: expect (t.sec).to_be (1) - it scans into min: expect (t.min).to_be (2) - it scans into hour: expect (t.hour).to_be (3) - it scans into monthday: expect (t.monthday).to_be (4) - it scans into month: expect (t.month).to_be (6) - it scans into year: expect (t.year).to_be (1906) - describe setlogmask: - context with bad arguments: if posix.setlogmask then badargs.diagnose (posix.setlogmask, "setlogmask (?int*)") end - describe sysconf: - before: sysconf, typeerrors = init (posix, "sysconf") # posix.sysconf takes an optional string or table as its first # argument, followed by zero or more strings only if the first # argument was a string; since we can't express that with # `badargs.diagnose` do it all manually again... - context with bad arguments: - 'it diagnoses argument #1 type not table, string or nil': expect (sysconf (false)). to_raise.any_of (typeerrors (1, "?table|string", "boolean")) - 'it diagnoses argument #1 string invalid': | expect (sysconf ("fubar")).to_raise.any_of { "bad argument #1 to '?' (invalid option 'fubar')", "bad argument #1 to 'sysconf' (invalid option 'fubar')", } - 'it diagnoses argument #2 type not string': expect (sysconf ("ARG_MAX", false)). to_raise.any_of (typeerrors (2, "string", "boolean")) - it diagnoses too many arguments: expect (sysconf ({}, false)).to_raise.any_of (typeerrors (2)) - it fetches the maximum number of exec arguments: expect (type (sysconf ().ARG_MAX)).to_be "number" expect (sysconf "ARG_MAX" >= 0).to_be (true) - it fetches the number processes per user: expect (type (sysconf ().CHILD_MAX)).to_be "number" expect (sysconf "CHILD_MAX" >= 0).to_be (true) - it fetches the number of clock ticks per second: expect (type (sysconf ().CLK_TCK)).to_be "number" expect (sysconf "CLK_TCK" >= 0).to_be (true) - it fetches the job control version: expect (type (sysconf ().JOB_CONTROL)).to_be "number" expect (sysconf "JOB_CONTROL" >= 0).to_be (true) - it fetches the maximum number of groups: expect (type (sysconf ().NGROUPS_MAX)).to_be "number" expect (sysconf "NGROUPS_MAX" >= 0).to_be (true) - it fetches the maximum number of open descriptors: expect (type (sysconf ().OPEN_MAX)).to_be "number" expect (sysconf "OPEN_MAX" >= 0).to_be (true) - it fetches the number of saved ids: expect (type (sysconf ().SAVED_IDS)).to_be "number" expect (sysconf "SAVED_IDS" >= 0).to_be (true) - it fetches the maximum number of open streams: expect (type (sysconf ().STREAM_MAX)).to_be "number" expect (sysconf "STREAM_MAX" >= 0).to_be (true) - it fetches the maximum length of a timezone name: expect (type (sysconf ().TZNAME_MAX)).to_be "number" expect (sysconf "TZNAME_MAX" >= 0).to_be (true) - "it fetches the POSIX.1 version": expect (type (sysconf ().VERSION)).to_be "number" expect (sysconf "VERSION" >= 0).to_be (true) - it fetches a subtable of named fields: expect ({sysconf ("VERSION", "ARG_MAX", "OPEN_MAX")}). to_equal {sysconf "VERSION", sysconf "ARG_MAX", sysconf "OPEN_MAX"} - it fetches everything without an argument: t = sysconf () for k, v in pairs (t) do expect (t[k]).to_be (sysconf (k)) end - describe times: - before: table.unpack = table.unpack or unpack times, typeerrors = init (posix, "times") # posix.times takes an optional string or table as its first # argument, followed by zero or more strings only if the first # argument was a string; since we can't express that with # `badargs.diagnose` do it all manually again... - context with bad arguments: - 'it diagnoses argument #1 type not table, string or nil': expect (times (false)). to_raise.any_of (typeerrors (1, "?table|string", "boolean")) - 'it diagnoses argument #1 string invalid': | expect (times ("fubar")).to_raise.any_of { "bad argument #1 to '?' (invalid option 'fubar')", "bad argument #1 to 'times' (invalid option 'fubar')", } - 'it diagnoses argument #2 type not string': expect (times ("utime", false)). to_raise.any_of (typeerrors (2, "string", "boolean")) - it diagnoses too many arguments: expect (times ({}, false)).to_raise.any_of (typeerrors (2)) - it fetches the user time: expect (type (times ().utime)).to_be "number" expect (times ("utime") >= 0).to_be (true) - it fetches the system time: expect (type (times ().stime)).to_be "number" expect (times ("stime") >= 0).to_be (true) - it fetches the children user time: expect (type (times ().cutime)).to_be "number" expect (times ("cutime") >= 0).to_be (true) - it fetches the children system time: expect (type (times ().cstime)).to_be "number" expect (times ("cstime") >= 0).to_be (true) - it fetches the elapsed time: expect (type (times ().elapsed)).to_be "number" expect (times ("elapsed") >= 0).to_be (true) - it fetches a subtable of named fields: | keys = {"utime", "cutime"} t = {times (table.unpack (keys))} for _, v in ipairs (t) do expect (type (v)).to_be "number" end - it fetches everything without an argument: keys = {"utime", "stime", "cutime", "cstime", "elapsed"} t = times () expect (t).to_contain.all_of (keys) for _, v in ipairs (keys) do expect (type (t[v])).to_be "number" end - describe umask: - before: stat, umask = posix.stat, posix.umask saved = umask () umask "rwxr-x---" dir = posix.mkdtemp (template) - after: rmtmp (dir) umask (saved) - context with bad arguments: | examples { ["it diagnoses argument #1 invalid mode"] = function () expect (umask ("g+vv")).to_raise.any_of { "bad argument #1 to '?' (bad mode)", "bad argument #1 to 'umask' (bad mode)", } end } badargs.diagnose (umask, "umask (?string)") - it returns current umask: expect (umask ()).to_be "rwxr-x---" - "it sets attributes with '='": expect (umask "a=r").to_be "r--r--r--" - "it adds attributes with '+'": expect (umask "g+w").to_be "rwxrwx---" - "it removes attributes with '-'": expect (umask "u-r").to_be "-wxr-x---" - it accepts comma separated attribute specifications: expect (umask "a+r,g+w,u-x").to_be "rw-rwxr--" - it controls the mode of newly created files: xxx, mode = dir .. "/xxx", "rw--w-r--" umask (mode) touch (xxx) expect (stat (xxx, "mode")).to_be (mode) os.remove (xxx) - describe uname: - before: uname = posix.uname - context with bad arguments: | badargs.diagnose (uname, "uname (?string)") examples { ['it diagnoses bad specifier format options'] = function () expect (uname ("foo %_")). to_error "bad argument #1 to 'uname' (invalid format option '_')" end } - it substitutes %n: expect (uname "%n").to_be (cmd_output "uname -n") - it substitutes %m: expect (uname "%m").to_be (cmd_output "uname -m") - it substitutes %r: expect (uname "%r").to_be (cmd_output "uname -r") - it outputs everything with no arguments: expect (uname ()).to_be (cmd_output "uname -s -n -r -v -m")