github.com/markusbkk/elvish@v0.0.0-20231204143114-91dc52438621/pkg/eval/builtin_fn_io_test.go (about) 1 package eval_test 2 3 import ( 4 "encoding/json" 5 "os" 6 "testing" 7 8 "github.com/markusbkk/elvish/pkg/eval" 9 "github.com/markusbkk/elvish/pkg/eval/errs" 10 . "github.com/markusbkk/elvish/pkg/eval/evaltest" 11 "github.com/markusbkk/elvish/pkg/eval/vals" 12 ) 13 14 func TestPut(t *testing.T) { 15 Test(t, 16 That(`put foo bar`).Puts("foo", "bar"), 17 That(`put $nil`).Puts(nil), 18 19 thatOutputErrorIsBubbled("put foo"), 20 ) 21 } 22 23 func TestReadUpto(t *testing.T) { 24 Test(t, 25 That("print abcd | read-upto c").Puts("abc"), 26 // read-upto does not consume more than needed 27 That("print abcd | { read-upto c; slurp }").Puts("abc", "d"), 28 // read-upto reads up to EOF 29 That("print abcd | read-upto z").Puts("abcd"), 30 That("print abcd | read-upto cd").Throws( 31 errs.BadValue{What: "terminator", 32 Valid: "a single ASCII character", Actual: "cd"}), 33 thatOutputErrorIsBubbled("print abcd | read-upto c"), 34 ) 35 } 36 37 func TestReadLine(t *testing.T) { 38 Test(t, 39 That(`print eof-ending | read-line`).Puts("eof-ending"), 40 That(`print "lf-ending\n" | read-line`).Puts("lf-ending"), 41 That(`print "crlf-ending\r\n" | read-line`).Puts("crlf-ending"), 42 That(`print "extra-cr\r\r\n" | read-line`).Puts("extra-cr\r"), 43 thatOutputErrorIsBubbled(`print eof-ending | read-line`), 44 ) 45 } 46 47 func TestPrint(t *testing.T) { 48 Test(t, 49 That(`print [foo bar]`).Prints("[foo bar]"), 50 That(`print foo bar &sep=,`).Prints("foo,bar"), 51 thatOutputErrorIsBubbled("print foo"), 52 ) 53 } 54 55 func TestEcho(t *testing.T) { 56 Test(t, 57 That(`echo [foo bar]`).Prints("[foo bar]\n"), 58 thatOutputErrorIsBubbled("echo foo"), 59 ) 60 } 61 62 func TestPprint(t *testing.T) { 63 Test(t, 64 That(`pprint [foo bar]`).Prints("[\n foo\n bar\n]\n"), 65 thatOutputErrorIsBubbled("pprint foo"), 66 ) 67 } 68 69 func TestReprCmd(t *testing.T) { 70 Test(t, 71 That(`repr foo bar ['foo bar']`).Prints("foo bar ['foo bar']\n"), 72 thatOutputErrorIsBubbled("repr foo"), 73 ) 74 } 75 76 func TestShow(t *testing.T) { 77 Test(t, 78 // A sanity test that show writes something. 79 That(`show ?(fail foo) | !=s (slurp) ''`).Puts(true), 80 thatOutputErrorIsBubbled("repr ?(fail foo)"), 81 ) 82 } 83 84 func TestOnlyBytesAndOnlyValues(t *testing.T) { 85 Test(t, 86 // Baseline 87 That(`{ print bytes; put values }`).Prints("bytes").Puts("values"), 88 That(`{ print bytes; put values } | only-bytes`).Prints("bytes").Puts(), 89 thatOutputErrorIsBubbled("{ print bytes; put values } | only-bytes"), 90 ) 91 } 92 93 func TestOnlyValues(t *testing.T) { 94 Test(t, 95 // Baseline 96 That(`{ print bytes; put values }`).Prints("bytes").Puts("values"), 97 That(`{ print bytes; put values } | only-values`).Prints("").Puts("values"), 98 thatOutputErrorIsBubbled("{ print bytes; put values } | only-values"), 99 ) 100 } 101 102 func TestSlurp(t *testing.T) { 103 Test(t, 104 That(`print "a\nb" | slurp`).Puts("a\nb"), 105 thatOutputErrorIsBubbled(`print "a\nb" | slurp`), 106 ) 107 } 108 109 func TestFromLines(t *testing.T) { 110 Test(t, 111 That(`print "a\nb" | from-lines`).Puts("a", "b"), 112 That(`print "a\nb\n" | from-lines`).Puts("a", "b"), 113 thatOutputErrorIsBubbled(`print "a\nb\n" | from-lines`), 114 ) 115 } 116 117 func TestFromTerminated(t *testing.T) { 118 Test(t, 119 That(`print "a\nb\x00\x00c\x00d" | from-terminated "\x00"`).Puts("a\nb", "", "c", "d"), 120 That(`print "a\x00b\x00" | from-terminated "\x00"`).Puts("a", "b"), 121 That(`print aXbXcXXd | from-terminated "X"`).Puts("a", "b", "c", "", "d"), 122 That(`from-terminated "xyz"`).Throws( 123 errs.BadValue{What: "terminator", 124 Valid: "a single ASCII character", Actual: "xyz"}), 125 thatOutputErrorIsBubbled("print aXbX | from-terminated X"), 126 ) 127 } 128 129 func TestFromJson(t *testing.T) { 130 Test(t, 131 That(`echo '{"k": "v", "a": [1, 2]}' '"foo"' | from-json`). 132 Puts(vals.MakeMap("k", "v", "a", vals.MakeList(1.0, 2.0)), 133 "foo"), 134 That(`echo '[null, "foo"]' | from-json`).Puts( 135 vals.MakeList(nil, "foo")), 136 That(`echo 'invalid' | from-json`).Throws(ErrorWithType(&json.SyntaxError{})), 137 thatOutputErrorIsBubbled(`echo '[]' | from-json`), 138 ) 139 } 140 141 func TestToLines(t *testing.T) { 142 Test(t, 143 That(`put "l\norem" ipsum | to-lines`).Prints("l\norem\nipsum\n"), 144 thatOutputErrorIsBubbled("to-lines [foo]"), 145 ) 146 } 147 148 func TestToTerminated(t *testing.T) { 149 Test(t, 150 That(`put "l\norem" ipsum | to-terminated "\x00"`).Prints("l\norem\x00ipsum\x00"), 151 That(`to-terminated "X" [a b c]`).Prints("aXbXcX"), 152 That(`to-terminated "XYZ" [a b c]`).Throws( 153 errs.BadValue{What: "terminator", 154 Valid: "a single ASCII character", Actual: "XYZ"}), 155 thatOutputErrorIsBubbled(`to-terminated "X" [a b c]`), 156 ) 157 } 158 159 func TestToJson(t *testing.T) { 160 Test(t, 161 That(`put [&k=v &a=[1 2]] foo | to-json`). 162 Prints(`{"a":["1","2"],"k":"v"} 163 "foo" 164 `), 165 That(`put [$nil foo] | to-json`).Prints("[null,\"foo\"]\n"), 166 thatOutputErrorIsBubbled("to-json [foo]"), 167 ) 168 } 169 170 func TestPrintf(t *testing.T) { 171 Test(t, 172 That(`printf abcd`).Prints("abcd"), 173 174 That(`printf "%s\n%s\n" abc xyz`).Prints("abc\nxyz\n"), 175 That(`printf "%q" "abc xyz"`).Prints(`'abc xyz'`), 176 That(`printf "%q" ['a b']`).Prints(`['a b']`), 177 That(`printf "%v" abc`).Prints("abc"), 178 That(`printf "%#v" "abc xyz"`).Prints(`'abc xyz'`), 179 That(`printf '%5.3s' 3.1415`).Prints(" 3.1"), 180 That(`printf '%5.3s' (float64 3.1415)`).Prints(" 3.1"), 181 182 That(`printf '%t' $true`).Prints("true"), 183 That(`printf '%t' $nil`).Prints("false"), 184 185 That(`printf '%3d' (num 5)`).Prints(" 5"), 186 That(`printf '%3d' 5`).Prints(" 5"), 187 That(`printf '%08b' (num 5)`).Prints("00000101"), 188 That(`printf '%08b' 5`).Prints("00000101"), 189 190 That(`printf '%.1f' 3.1415`).Prints("3.1"), 191 That(`printf '%.1f' (float64 3.1415)`).Prints("3.1"), 192 193 // Does not interpret escape sequences 194 That(`printf '%s\n%s\n' abc xyz`).Prints("abc\\nxyz\\n"), 195 196 // Error cases 197 198 // Float verb with argument that can't be converted to float 199 That(`printf '%f' 1.3x`).Prints("%!f(cannot parse as number: 1.3x)"), 200 // Integer verb with argument that can't be converted to integer 201 That(`printf '%d' 3.5`).Prints("%!d(cannot parse as integer: 3.5)"), 202 // Unsupported verb 203 That(`printf '%A' foo`).Prints("%!A(unsupported formatting verb)"), 204 205 thatOutputErrorIsBubbled("printf foo"), 206 ) 207 } 208 209 func thatOutputErrorIsBubbled(code string) Case { 210 return That(code + " >&-").Throws(OneOfErrors(os.ErrInvalid, eval.ErrNoValueOutput)) 211 }