1before:
2  this_module = 'posix.stdlib'
3  global_table = '_G'
4
5  M = require(this_module)
6
7
8specify posix.stdlib:
9- context when required:
10  - it does not touch the global table:
11      expect(show_apis {added_to=global_table, by=this_module}).
12         to_equal {}
13
14
15- describe abort:
16  - context with bad arguments:
17      badargs.diagnose(M.abort, "()")
18
19
20- describe getenv:
21  - before:
22      getenv = M.getenv
23
24  - context with bad arguments:
25      badargs.diagnose(getenv, "(?string)")
26
27  - it fetches a table of process environment variables: |
28      volatile = { _=true, CWD=true, LUA_PATH=true, PWD=true, SHLVL=true, }
29      ESC = string.char(27)
30      for k,v in pairs(getenv()) do
31         if not volatile[k] then
32            expect(hell.spawn('echo "' .. k .. '=$' .. k .. '" | tr "' .. ESC .. '" "^"')).
33               to_contain_output(k .. "=" .. string.gsub(v, '\\033', '^'))
34         end
35      end
36  - it fetches a named process environment variable:
37      expect(getenv "USER").to_be(cmd_output('echo "$USER"'))
38      expect(getenv "HOME").to_be(cmd_output('echo "$HOME"'))
39      expect(getenv "SHELL").to_be(cmd_output('echo "$SHELL"'))
40  - it returns nil for an absent environment setting:
41      expect(getenv "very_unlikely_to_be_set").to_be(nil)
42
43
44- describe grantpt:
45  - context with bad arguments:
46      badargs.diagnose(M.grantpt, "(int)")
47
48
49- describe mkdtemp:
50  - before:
51      st = require "posix.sys.stat"
52      mkdtemp = M.mkdtemp
53      stat, IFMT, IFDIR, IRWXU = st.stat, st.S_IFMT, st.S_IFDIR, st.S_IRWXU
54      IRWXA = bor(st.S_IRWXU, st.S_IRWXG, st.S_IRWXO)
55
56  - context with bad arguments:
57      badargs.diagnose(mkdtemp, "(string)")
58
59  - it creates a temporary directory from a template:
60      dir, errmsg = mkdtemp(template)
61      expect(dir).not_to_be(nil)
62      dirstat = stat(dir)
63      expect(band(dirstat.st_mode, IFMT)).to_be(IFDIR)
64      expect(band(dirstat.st_mode, IRWXA)).to_be(IRWXU)
65      rmtmp(dir)
66
67
68- describe mkstemp:
69  - before:
70      fc = require "posix.fcntl"
71      st = require "posix.sys.stat"
72      unistd = require "posix.unistd"
73      O_RDONLY, open = fc.O_RDONLY, fc.open
74      mkstemp = M.mkstemp
75      close, isatty, read, write =
76         unistd.close, unistd.isatty, unistd.read, unistd.write
77      stat, IFMT, IFREG = st.stat, st.S_IFMT, st.S_IFREG
78      IRW_U = bor(st.S_IRUSR, st.S_IWUSR)
79      IRWXA = bor(st.S_IRWXU, st.S_IRWXG, st.S_IRWXO)
80      fd, path = mkstemp(template)
81  - after:
82      close(fd)
83      os.remove(path)
84
85  - context with bad arguments:
86      badargs.diagnose(mkstemp, "(string)")
87
88  - it creates a temporary file from a template:
89      expect(fd).not_to_be(nil)
90      write(fd, "12345")
91      expect(isatty(fd)).not_to_be(true)
92      fstat = stat(path)
93      expect(band(fstat.st_mode, IFMT)).to_be(IFREG)
94      expect(band(fstat.st_mode, IRWXA)).to_be(IRW_U)
95      expect(fstat.st_size).to_be(5)
96      fd2 = open(path, O_RDONLY)
97      expect(read(fd2, 5)).to_be "12345"
98      close(fd2)
99  - it creates a new temporary file on each call:
100      fd2, another = mkstemp(template)
101      expect(fd2).not_to_be(fd)
102      expect(another).not_to_be(path)
103      close(fd2)
104      os.remove(another)
105
106
107- describe openpt:
108  - before:
109      fc = require "posix.fcntl"
110      st = require "posix.sys.stat"
111      close = require "posix.unistd".close
112      grantpt, openpt, ptsname, unlockpt =
113         M.grantpt, M.openpt, M.ptsname, M.unlockpt
114      O_RDWR, O_NOCTTY, open = fc.O_RDWR, fc.O_NOCTTY, fc.open
115      stat, IFMT, IFCHR = st.stat, st.S_IFMT, st.S_IFCHR
116
117  - context with bad arguments:
118      badargs.diagnose(openpt, "(int)")
119
120  - it can create a pseudoterminal:
121      masterfd = openpt(bor(O_RDWR, O_NOCTTY))
122      expect(type(masterfd)).to_be "number"
123      expect(masterfd > 0).to_be(true)
124      expect(Emsg(grantpt(masterfd))).to_be ""
125      expect(Emsg(unlockpt(masterfd))).to_be ""
126      slavename = ptsname(masterfd)
127      slavestat = stat(slavename)
128      expect(band(slavestat.st_mode, IFMT)).to_be(IFCHR)
129      slavefd = open(slavename, bor(O_RDWR, O_NOCTTY))
130      expect(type(slavefd)).to_be "number"
131      expect(slavefd > 0).to_be(true)
132      close(slavefd)
133      close(masterfd)
134
135
136- describe ptsname:
137  - context with bad arguments:
138      badargs.diagnose(M.ptsname, "(int)")
139
140
141- describe realpath:
142  - context with bad arguments:
143      badargs.diagnose(M.realpath, "(string)")
144
145
146- describe setenv:
147  - before:
148      getenv, setenv = M.getenv, M.setenv
149
150  - context with bad arguments:
151      badargs.diagnose(M.setenv, "(string, ?string, ?any)")
152
153  - it sets a new value in the process environment:
154      setenv("MYVAR", "123")
155      expect(getenv "MYVAR").to_be "123"
156      setenv("MYVAR", nil)
157      expect(getenv "MYVAR").to_be(nil)
158
159
160- describe unlockpt:
161  - context with bad arguments:
162      badargs.diagnose(M.unlockpt, "(int)")
163