1before: | 2 base_module = "debug" 3 this_module = "std.debug" 4 global_table = "_G" 5 6 extend_base = { "DEPRECATED", "DEPRECATIONMSG", "argcheck", "argerror", 7 "argscheck", "extramsg_mismatch", "extramsg_toomany", 8 "getfenv", "parsetypes", "resulterror", "setfenv", "say", 9 "toomanyargmsg", "typesplit", "trace", "_setdebug" } 10 11 M = require (this_module) 12 13specify std.debug: 14- context when required: 15 - context by name: 16 - it does not touch the global table: 17 expect (show_apis {added_to=global_table, by=this_module}). 18 to_equal {} 19 - it does not touch the core debug table: 20 expect (show_apis {added_to=base_module, by=this_module}). 21 to_equal {} 22 - it contains apis from the core debug table: 23 expect (show_apis {from=base_module, not_in=this_module}). 24 to_contain.a_permutation_of (extend_base) 25 26 - context via the std module: 27 - it does not touch the global table: 28 expect (show_apis {added_to=global_table, by="std"}). 29 to_equal {} 30 - it does not touch the core debug table: 31 expect (show_apis {added_to=base_module, by="std"}). 32 to_equal {} 33 34 35- describe DEPRECATED: 36 - before: | 37 function runscript (body, name, args) 38 return luaproc ( 39 "require '" .. this_module .. "'.DEPRECATED ('0', '" .. 40 (name or "runscript") .. "', function (...)" .. 41 " " .. body .. 42 " end) " .. 43 "('" .. table.concat (args or {}, "', '") .. "')" 44 ) 45 end 46 47 f, badarg = init (M, this_module, "DEPRECATED") 48 49 - it returns a function: 50 expect (type (f ("0", "deprecated", nop))).to_be "function" 51 expect (f ("0", "deprecated", nop)).not_to_be (nop) 52 - context with deprecated function: 53 - it executes the deprecated function: 54 expect (runscript 'error "oh noes!"').to_contain_error "oh noes!" 55 - it passes arguments to the deprecated function: 56 expect (runscript ("print (table.concat ({...}, ', '))", nil, 57 {"foo", "bar", "baz"})).to_output "foo, bar, baz\n" 58 - it returns deprecated function results: | 59 script = [[ 60 DEPRECATED = require "std.debug".DEPRECATED 61 fn = DEPRECATED ("0", "fn", function () return "foo", "bar", "baz" end) 62 print (fn ()) 63 ]] 64 expect (luaproc (script)).to_output "foo\tbar\tbaz\n" 65 - it writes a warning to stderr: 66 expect (runscript 'error "oh noes!"'). 67 to_match_error "deprecated.*, and will be removed" 68 - it writes the version string to stderr: 69 expect (runscript 'error "oh noes!"'). 70 to_contain_error "in release 0" 71 - it writes the call location to stderr: | 72 expect (runscript 'error "oh noes!"'). 73 to_match_error "^%S+:1: " 74 - context with _DEBUG: 75 - before: | 76 script = [[ 77 DEPRECATED = require "]] .. this_module .. [[".DEPRECATED 78 fn = DEPRECATED ("0", "fn", function () io.stderr:write "oh noes!\n" end) 79 fn () -- line 3 80 fn () -- line 4 81 ]] 82 - it warns every call by default: 83 expect (luaproc (script)).to_match_error "^%S+:3:.*deprecated" 84 expect (luaproc (script)).to_match_error "\n%S+:4:.*deprecated" 85 - it does not warn at all with _DEBUG set to false: 86 script = "_DEBUG = false " .. script 87 expect (luaproc (script)).not_to_match_error "%d:.*deprecated" 88 - it does not define the function with _DEBUG set to true: | 89 script = "_DEBUG = true " .. script 90 expect (luaproc (script)).to_contain_error.any_of { 91 ":3: attempt to call global 'fn'", 92 ":3: attempt to call a nil value (global 'fn')", 93 } 94 - it warns on every call with _DEBUG.deprecate unset: 95 script = "_DEBUG = {} " .. script 96 expect (luaproc (script)).to_match_error "^%S+:3:.*deprecated" 97 expect (luaproc (script)).to_match_error "\n%S+:4:.*deprecated" 98 - it does not warn at all with _DEBUG.deprecate set to false: 99 script = "_DEBUG = { deprecate = false } " .. script 100 expect (luaproc (script)).not_to_match_error "%d:.*deprecated" 101 - it warns on every call with _DEBUG.deprecate set to true: | 102 script = "_DEBUG = { deprecate = true } " .. script 103 expect (luaproc (script)).to_contain_error.any_of { 104 ":3: attempt to call global 'fn'", 105 ":3: attempt to call a nil value (global 'fn')", 106 } 107 108 109- describe DEPRECATIONMSG: 110 - before: | 111 function mkscript (lvl) 112 return [[ 113 DEPRECATIONMSG = require "]] .. this_module .. [[".DEPRECATIONMSG 114 function fn () 115 io.stderr:write (DEPRECATIONMSG ("42", "spec file", ]] .. lvl .. [[)) 116 end 117 fn () -- line 5 118 fn () -- line 6 119 ]] 120 end 121 122 f = M.DEPRECATIONMSG 123 124 - it contains deprecating the release version: 125 expect (f ("41", "foo", 2)).to_contain "41" 126 - it contains the deprecation function name: 127 expect (f ("41", "some.module.fname", 2)).to_contain "some.module.fname" 128 - it appends an optional extra message: 129 expect (f ("41", "wuh", "ah boo", 2)).to_contain ", ah boo." 130 - it blames the given stack level: 131 expect (luaproc (mkscript (1))).to_match_error "^%S+:3:.*deprecated" 132 expect (luaproc (mkscript (2))).to_match_error "^%S+:5:.*deprecated" 133 134 135- describe resulterror: 136 - before: | 137 function mkstack (level) 138 return string.format ([[ 139 _DEBUG = true -- line 1 140 local debug = require "std.debug" -- line 2 141 function ohnoes () -- line 3 142 debug.resulterror ("ohnoes", 1, nil, %s) -- line 4 143 end -- line 5 144 function caller () -- line 6 145 local r = ohnoes () -- line 7 146 return "not a tail call" -- line 8 147 end -- line 9 148 caller () -- line 10 149 ]], tostring (level)) 150 end 151 152 f = M.resulterror 153 154 - it blames the call site by default: | 155 expect (luaproc (mkstack ())).to_contain_error ":4: bad result" 156 - it honors optional call stack level reporting: | 157 expect (luaproc (mkstack (1))).to_contain_error ":4: bad result" 158 expect (luaproc (mkstack (2))).to_contain_error ":7: bad result" 159 - it reports the calling function name: 160 expect (f ('expect', 1)).to_raise "'expect'" 161 - it reports the argument number: | 162 expect (f ('expect', 12345)).to_raise "#12345" 163 - it reports extra message in parentheses: 164 expect (f ('expect', 1, "extramsg")).to_raise " (extramsg)" 165 166 167- describe argerror: 168 - before: | 169 function mkstack (level) 170 return string.format ([[ 171 _DEBUG = true -- line 1 172 local debug = require "std.debug" -- line 2 173 function ohnoes () -- line 3 174 debug.argerror ("ohnoes", 1, nil, %s) -- line 4 175 end -- line 5 176 function caller () -- line 6 177 local r = ohnoes () -- line 7 178 return "not a tail call" -- line 8 179 end -- line 9 180 caller () -- line 10 181 ]], tostring (level)) 182 end 183 184 f, badarg = init (M, this_module, "argerror") 185 186 - it diagnoses missing arguments: 187 pending "Lua 5.1 support is dropped" 188 expect (f ()).to_raise (badarg (1, "string")) 189 expect (f "foo").to_raise (badarg (2, "int")) 190 - it diagnoses wrong argument types: 191 pending "Lua 5.1 support is dropped" 192 expect (f (false)).to_raise (badarg (1, "string", "boolean")) 193 expect (f ("foo", false)).to_raise (badarg (2, "int", "boolean")) 194 expect (f ("foo", 1, false)). 195 to_raise (badarg (3, "string or nil", "boolean")) 196 expect (f ("foo", 1, "bar", false)). 197 to_raise (badarg (4, "int or nil", "boolean")) 198 - it diagnoses too many arguments: 199 pending "Lua 5.1 support is dropped" 200 expect (f ("foo", 1, "bar", 2, false)).to_raise (badarg (5)) 201 202 - it blames the call site by default: | 203 expect (luaproc (mkstack ())).to_contain_error ":4: bad argument" 204 - it honors optional call stack level reporting: | 205 expect (luaproc (mkstack (1))).to_contain_error ":4: bad argument" 206 expect (luaproc (mkstack (2))).to_contain_error ":7: bad argument" 207 - it reports the calling function name: 208 expect (f ('expect', 1)).to_raise "'expect'" 209 - it reports the argument number: | 210 expect (f ('expect', 12345)).to_raise "#12345" 211 - it reports extra message in parentheses: 212 expect (f ('expect', 1, "extramsg")).to_raise " (extramsg)" 213 214 215- describe argcheck: 216 - before: | 217 Object = require 'std.object' 218 List = Object { _type = "List" } 219 Foo = Object { _type = "Foo" } 220 221 function fn (...) return M.argcheck ('expect', 1, ...) end 222 223 function mkstack (level, debugp) 224 return string.format ([[ 225 _DEBUG = %s -- line 1 226 local debug = require "std.debug" -- line 2 227 function ohnoes (t) -- line 3 228 debug.argcheck ("ohnoes", 1, "table", t, %s) -- line 4 229 end -- line 5 230 function caller () -- line 6 231 local r = ohnoes "not a table" -- line 7 232 return "not a tail call" -- line 8 233 end -- line 9 234 caller () -- line 10 235 ]], tostring (debugp), tostring (level)) 236 end 237 238 f, badarg = init (M, this_module, "argcheck") 239 240 - it diagnoses missing arguments: 241 pending "Lua 5.1 support is dropped" 242 expect (f ()).to_raise (badarg (1, "string")) 243 expect (f "foo").to_raise (badarg (2, "int")) 244 expect (f ("foo", 1)).to_raise (badarg (3, "string")) 245 - it diagnoses wrong argument types: 246 pending "Lua 5.1 support is dropped" 247 expect (f (false)).to_raise (badarg (1, "string", "boolean")) 248 expect (f ("foo", false)).to_raise (badarg (2, "int", "boolean")) 249 expect (f ("foo", 1, false)).to_raise (badarg (3, "string", "boolean")) 250 expect (f ("foo", 1, "bar", 2, false)). 251 to_raise (badarg (5, "int or nil", "boolean")) 252 - it diagnoses too many arguments: 253 pending "Lua 5.1 support is dropped" 254 expect (f ("foo", 1, "bar", 2, 3, false)).to_raise (badarg (6)) 255 256 - it blames the calling function by default: | 257 expect (luaproc (mkstack ())).to_contain_error ":7: bad argument" 258 - it honors optional call stack level reporting: | 259 expect (luaproc (mkstack (1))).to_contain_error ":4: bad argument" 260 expect (luaproc (mkstack (2))).to_contain_error ":7: bad argument" 261 expect (luaproc (mkstack (3))).to_contain_error ":10: bad argument" 262 - it can be disabled by setting _DEBUG to false: 263 expect (luaproc (mkstack (nil, false))). 264 not_to_contain_error "bad argument" 265 - it can be disabled by setting _DEBUG.argcheck to false: 266 expect (luaproc (mkstack (nil, "{ argcheck = false }"))). 267 not_to_contain_error "bad argument" 268 - it is not disabled by setting _DEBUG.argcheck to true: 269 expect (luaproc (mkstack (nil, "{ argcheck = true }"))). 270 to_contain_error "bad argument" 271 - it is not disabled by leaving _DEBUG.argcheck unset: 272 expect (luaproc (mkstack (nil, "{}"))). 273 to_contain_error "bad argument" 274 275 - context with primitives: 276 - it diagnoses missing types: 277 expect (fn ("bool", nil)).to_raise "boolean expected, got no value" 278 expect (fn ("boolean", nil)).to_raise "boolean expected, got no value" 279 expect (fn ("file", nil)).to_raise "FILE* expected, got no value" 280 expect (fn ("number", nil)).to_raise "number expected, got no value" 281 expect (fn ("string", nil)).to_raise "string expected, got no value" 282 expect (fn ("table", nil)).to_raise "table expected, got no value" 283 - it diagnoses mismatched types: 284 expect (fn ("bool", {0})).to_raise "boolean expected, got table" 285 expect (fn ("boolean", {0})).to_raise "boolean expected, got table" 286 expect (fn ("file", {0})).to_raise "FILE* expected, got table" 287 expect (fn ("number", {0})).to_raise "number expected, got table" 288 expect (fn ("string", {0})).to_raise "string expected, got table" 289 expect (fn ("table", false)).to_raise "table expected, got boolean" 290 - it matches types: 291 expect (fn ("bool", true)).not_to_raise "any error" 292 expect (fn ("boolean", true)).not_to_raise "any error" 293 expect (fn ("file", io.stderr)).not_to_raise "any error" 294 expect (fn ("number", 1)).not_to_raise "any error" 295 expect (fn ("string", "s")).not_to_raise "any error" 296 expect (fn ("table", {})).not_to_raise "any error" 297 expect (fn ("table", require "std.object")).not_to_raise "any error" 298 299 - context with int: 300 - it diagnoses missing types: 301 expect (fn ("int", nil)).to_raise "int expected, got no value" 302 - it diagnoses mismatched types: 303 expect (fn ("int", false)).to_raise "int expected, got boolean" 304 expect (fn ("int", 1.234)).to_raise "int expected, got number" 305 expect (fn ("int", 1234e-3)).to_raise "int expected, got number" 306 - it matches types: 307 expect (fn ("int", 1)).not_to_raise "any error" 308 expect (fn ("int", 1.0)).not_to_raise "any error" 309 expect (fn ("int", 0x1234)).not_to_raise "any error" 310 expect (fn ("int", 1.234e3)).not_to_raise "any error" 311 - context with constant string: 312 - it diagnoses missing types: 313 expect (fn (":foo", nil)).to_raise ":foo expected, got no value" 314 - it diagnoses mismatched types: 315 expect (fn (":foo", false)).to_raise ":foo expected, got boolean" 316 expect (fn (":foo", ":bar")).to_raise ":foo expected, got :bar" 317 expect (fn (":foo", "foo")).to_raise ":foo expected, got string" 318 - it matches types: 319 expect (fn (":foo", ":foo")).not_to_raise "any error" 320 - context with callable types: 321 - it diagnoses missing types: 322 expect (fn ("func", nil)).to_raise "function expected, got no value" 323 expect (fn ("function", nil)).to_raise "function expected, got no value" 324 - it diagnoses mismatched types: 325 expect (fn ("func", {0})).to_raise "function expected, got table" 326 expect (fn ("function", {0})).to_raise "function expected, got table" 327 - it matches types: 328 expect (fn ("func", function () end)).not_to_raise "any error" 329 expect (fn ("func", setmetatable ({}, {__call = function () end}))). 330 not_to_raise "any error" 331 expect (fn ("function", function () end)).not_to_raise "any error" 332 expect (fn ("function", setmetatable ({}, {__call = function () end}))). 333 not_to_raise "any error" 334 - context with table of homogenous elements: 335 - it diagnoses missing types: 336 expect (fn ("table of boolean", nil)). 337 to_raise "table expected, got no value" 338 expect (fn ("table of booleans", nil)). 339 to_raise "table expected, got no value" 340 - it diagnoses mismatched types: 341 expect (fn ("table of file", io.stderr)). 342 to_raise "table expected, got file" 343 expect (fn ("table of files", io.stderr)). 344 to_raise "table expected, got file" 345 - it diagnoses mismatched element types: 346 expect (fn ("table of number", {false})). 347 to_raise "table of numbers expected, got boolean at index 1" 348 expect (fn ("table of numbers", {1, 2, "3"})). 349 to_raise "table of numbers expected, got string at index 3" 350 expect (fn ("table of numbers", {a=1, b=2, c="3"})). 351 to_raise "table of numbers expected, got string at index c" 352 - it matches types: 353 expect (fn ("table of string", {})).not_to_raise "any error" 354 expect (fn ("table of string", {"foo"})).not_to_raise "any error" 355 expect (fn ("table of string", {"f", "o", "o"})).not_to_raise "any error" 356 expect (fn ("table of string", {b="b", a="a", r="r"})).not_to_raise "any error" 357 - context with non-empty table types: 358 - it diagnoses missing types: 359 expect (fn ("#table", nil)). 360 to_raise "non-empty table expected, got no value" 361 - it diagnoses mismatched types: 362 expect (fn ("#table", false)). 363 to_raise "non-empty table expected, got boolean" 364 expect (fn ("#table", {})). 365 to_raise "non-empty table expected, got empty table" 366 - it matches types: 367 expect (fn ("#table", {0})).not_to_raise "any error" 368 - context with non-empty table of homogenous elements: 369 - it diagnoses missing types: 370 expect (fn ("#table of boolean", nil)). 371 to_raise "non-empty table expected, got no value" 372 expect (fn ("#table of booleans", nil)). 373 to_raise "non-empty table expected, got no value" 374 - it diagnoses mismatched types: 375 expect (fn ("#table of file", {})). 376 to_raise "non-empty table expected, got empty table" 377 expect (fn ("#table of file", io.stderr)). 378 to_raise "non-empty table expected, got file" 379 - it diagnoses mismatched element types: 380 expect (fn ("#table of number", {false})). 381 to_raise "non-empty table of numbers expected, got boolean at index 1" 382 expect (fn ("#table of numbers", {1, 2, "3"})). 383 to_raise "non-empty table of numbers expected, got string at index 3" 384 expect (fn ("#table of numbers", {a=1, b=2, c="3"})). 385 to_raise "non-empty table of numbers expected, got string at index c" 386 - it matches types: 387 expect (fn ("#table of string", {"foo"})).not_to_raise "any error" 388 expect (fn ("#table of string", {"f", "o", "o"})).not_to_raise "any error" 389 expect (fn ("#table of string", {b="b", a="a", r="r"})).not_to_raise "any error" 390 - context with list: 391 - it diagnonses missing types: 392 expect (fn ("list", nil)). 393 to_raise "list expected, got no value" 394 - it diagnoses mismatched types: 395 expect (fn ("list", false)). 396 to_raise "list expected, got boolean" 397 expect (fn ("list", {foo=1})). 398 to_raise "list expected, got table" 399 expect (fn ("list", Object)). 400 to_raise "list expected, got Object" 401 - it matches types: 402 expect (fn ("list", {})).not_to_raise "any error" 403 expect (fn ("list", {1})).not_to_raise "any error" 404 - context with list of homogenous elements: 405 - it diagnoses missing types: 406 expect (fn ("list of boolean", nil)). 407 to_raise "list expected, got no value" 408 expect (fn ("list of booleans", nil)). 409 to_raise "list expected, got no value" 410 - it diagnoses mismatched types: 411 expect (fn ("list of file", io.stderr)). 412 to_raise "list expected, got file" 413 expect (fn ("list of files", io.stderr)). 414 to_raise "list expected, got file" 415 expect (fn ("list of files", {file=io.stderr})). 416 to_raise "list expected, got table" 417 - it diagnoses mismatched element types: 418 expect (fn ("list of number", {false})). 419 to_raise "list of numbers expected, got boolean at index 1" 420 expect (fn ("list of numbers", {1, 2, "3"})). 421 to_raise "list of numbers expected, got string at index 3" 422 - it matches types: 423 expect (fn ("list of string", {})).not_to_raise "any error" 424 expect (fn ("list of string", {"foo"})).not_to_raise "any error" 425 expect (fn ("list of string", {"f", "o", "o"})).not_to_raise "any error" 426 - context with non-empty list: 427 - it diagnonses missing types: 428 expect (fn ("#list", nil)). 429 to_raise "non-empty list expected, got no value" 430 - it diagnoses mismatched types: 431 expect (fn ("#list", false)). 432 to_raise "non-empty list expected, got boolean" 433 expect (fn ("#list", {})). 434 to_raise "non-empty list expected, got empty list" 435 expect (fn ("#list", {foo=1})). 436 to_raise "non-empty list expected, got table" 437 expect (fn ("#list", Object)). 438 to_raise "non-empty list expected, got empty Object" 439 expect (fn ("#list", List {})). 440 to_raise "non-empty list expected, got empty List" 441 - it matches types: 442 expect (fn ("#list", {1})).not_to_raise "any error" 443 - context with non-empty list of homogenous elements: 444 - it diagnoses missing types: 445 expect (fn ("#list of boolean", nil)). 446 to_raise "non-empty list expected, got no value" 447 expect (fn ("#list of booleans", nil)). 448 to_raise "non-empty list expected, got no value" 449 - it diagnoses mismatched types: 450 expect (fn ("#list of file", {})). 451 to_raise "non-empty list expected, got empty table" 452 expect (fn ("#list of file", io.stderr)). 453 to_raise "non-empty list expected, got file" 454 expect (fn ("#list of files", {file=io.stderr})). 455 to_raise "non-empty list expected, got table" 456 - it diagnoses mismatched element types: 457 expect (fn ("#list of number", {false})). 458 to_raise "non-empty list of numbers expected, got boolean at index 1" 459 expect (fn ("#list of numbers", {1, 2, "3"})). 460 to_raise "non-empty list of numbers expected, got string at index 3" 461 - it matches types: 462 expect (fn ("#list of string", {"foo"})).not_to_raise "any error" 463 expect (fn ("#list of string", {"f", "o", "o"})).not_to_raise "any error" 464 - context with container: 465 - it diagnoses missing types: 466 expect (fn ("List of boolean", nil)). 467 to_raise "List expected, got no value" 468 expect (fn ("List of booleans", nil)). 469 to_raise "List expected, got no value" 470 - it diagnoses mismatched types: 471 expect (fn ("List of file", io.stderr)). 472 to_raise "List expected, got file" 473 expect (fn ("List of files", io.stderr)). 474 to_raise "List expected, got file" 475 expect (fn ("List of files", {file=io.stderr})). 476 to_raise "List expected, got table" 477 - it diagnoses mismatched element types: 478 expect (fn ("List of number", List {false})). 479 to_raise "List of numbers expected, got boolean at index 1" 480 expect (fn ("List of numbers", List {1, 2, "3"})). 481 to_raise "List of numbers expected, got string at index 3" 482 - it matches types: 483 expect (fn ("list of string", List {})).not_to_raise "any error" 484 expect (fn ("list of string", List {"foo"})).not_to_raise "any error" 485 expect (fn ("list of string", List {"f", "o", "o"})).not_to_raise "any error" 486 - context with object: 487 - it diagnoses missing types: 488 expect (fn ("object", nil)).to_raise "object expected, got no value" 489 expect (fn ("Object", nil)).to_raise "Object expected, got no value" 490 expect (fn ("Foo", nil)).to_raise "Foo expected, got no value" 491 expect (fn ("any", nil)).to_raise "any value expected, got no value" 492 - it diagnoses mismatched types: 493 expect (fn ("object", {0})).to_raise "object expected, got table" 494 expect (fn ("Object", {0})).to_raise "Object expected, got table" 495 expect (fn ("object", {_type="Object"})).to_raise "object expected, got table" 496 expect (fn ("Object", {_type="Object"})).to_raise "Object expected, got table" 497 expect (fn ("Object", Foo)).to_raise "Object expected, got Foo" 498 expect (fn ("Foo", {0})).to_raise "Foo expected, got table" 499 expect (fn ("Foo", Object)).to_raise "Foo expected, got Object" 500 - it matches types: 501 expect (fn ("object", Object)).not_to_raise "any error" 502 expect (fn ("object", Object {})).not_to_raise "any error" 503 expect (fn ("object", Foo)).not_to_raise "any error" 504 expect (fn ("object", Foo {})).not_to_raise "any error" 505 - it matches anything: 506 expect (fn ("any", true)).not_to_raise "any error" 507 expect (fn ("any", {})).not_to_raise "any error" 508 expect (fn ("any", Object)).not_to_raise "any error" 509 expect (fn ("any", Foo {})).not_to_raise "any error" 510 - context with a list of valid types: 511 - it diagnoses missing elements: 512 expect (fn ("string|table", nil)). 513 to_raise "string or table expected, got no value" 514 expect (fn ("string|list|#table", nil)). 515 to_raise "string, list or non-empty table expected, got no value" 516 expect (fn ("string|number|list|object", nil)). 517 to_raise "string, number, list or object expected, got no value" 518 - it diagnoses mismatched elements: 519 expect (fn ("string|table", false)). 520 to_raise "string or table expected, got boolean" 521 expect (fn ("string|#table", {})). 522 to_raise "string or non-empty table expected, got empty table" 523 expect (fn ("string|number|#list|object", {})). 524 to_raise "string, number, non-empty list or object expected, got empty table" 525 - it matches any type from a list: 526 expect (fn ("string|table", "foo")).not_to_raise "any error" 527 expect (fn ("string|table", {})).not_to_raise "any error" 528 expect (fn ("string|table", {0})).not_to_raise "any error" 529 expect (fn ("table|table", {})).not_to_raise "any error" 530 expect (fn ("#table|table", {})).not_to_raise "any error" 531 - context with an optional type element: 532 - it diagnoses mismatched elements: 533 expect (fn ("?boolean", "string")). 534 to_raise "boolean or nil expected, got string" 535 expect (fn ("?boolean|:symbol", {})). 536 to_raise "boolean, :symbol or nil expected, got empty table" 537 - it matches nil against a single type: 538 expect (fn ("?any", nil)).not_to_raise "any error" 539 expect (fn ("?boolean", nil)).not_to_raise "any error" 540 expect (fn ("?string", nil)).not_to_raise "any error" 541 - it matches nil against a list of types: 542 expect (fn ("?boolean|table", nil)).not_to_raise "any error" 543 expect (fn ("?string|table", nil)).not_to_raise "any error" 544 expect (fn ("?table|#table", nil)).not_to_raise "any error" 545 expect (fn ("?#table|table", nil)).not_to_raise "any error" 546 - it matches nil against a list of optional types: 547 expect (fn ("?boolean|?table", nil)).not_to_raise "any error" 548 expect (fn ("?string|?table", nil)).not_to_raise "any error" 549 expect (fn ("?table|?#table", nil)).not_to_raise "any error" 550 expect (fn ("?#table|?table", nil)).not_to_raise "any error" 551 - it matches any named type: 552 expect (fn ("?any", false)).not_to_raise "any error" 553 expect (fn ("?boolean", false)).not_to_raise "any error" 554 expect (fn ("?string", "string")).not_to_raise "any error" 555 - it matches any type from a list: 556 expect (fn ("?boolean|table", {})).not_to_raise "any error" 557 expect (fn ("?string|table", {0})).not_to_raise "any error" 558 expect (fn ("?table|#table", {})).not_to_raise "any error" 559 expect (fn ("?#table|table", {})).not_to_raise "any error" 560 - it matches any type from a list with several optional specifiers: 561 expect (fn ("?boolean|?table", {})).not_to_raise "any error" 562 expect (fn ("?string|?table", {0})).not_to_raise "any error" 563 expect (fn ("?table|?table", {})).not_to_raise "any error" 564 expect (fn ("?#table|?table", {})).not_to_raise "any error" 565 566 567- describe debug: 568 - before: | 569 function mkwrap (k, v) 570 local fmt = "%s" 571 if type (v) == "string" then fmt = "%q" end 572 return k, string.format (fmt, require "std".tostring (v)) 573 end 574 575 function mkdebug (debugp, ...) 576 return string.format ([[ 577 _DEBUG = %s 578 require "std.debug" (%s) 579 ]], 580 require "std".tostring (debugp), 581 table.concat (require "std.functional".map (mkwrap, {...}), ", ")) 582 end 583 584 - it does nothing when _DEBUG is disabled: 585 expect (luaproc (mkdebug (false, "nothing to see here"))). 586 not_to_contain_error "nothing to see here" 587 - it writes to stderr when _DEBUG is not set: 588 expect (luaproc (mkdebug (nil, "debugging"))). 589 to_contain_error "debugging" 590 - it writes to stderr when _DEBUG is enabled: 591 expect (luaproc (mkdebug (true, "debugging"))). 592 to_contain_error "debugging" 593 - it writes to stderr when _DEBUG.level is not set: 594 expect (luaproc (mkdebug ({}, "debugging"))). 595 to_contain_error "debugging" 596 - it writes to stderr when _DEBUG.level is specified: 597 expect (luaproc (mkdebug ({level = 0}, "debugging"))). 598 to_contain_error "debugging" 599 expect (luaproc (mkdebug ({level = 1}, "debugging"))). 600 to_contain_error "debugging" 601 expect (luaproc (mkdebug ({level = 2}, "debugging"))). 602 to_contain_error "debugging" 603 604 605- describe argscheck: 606 - before: | 607 function mkstack (name, spec) 608 return string.format ([[ 609 local argscheck = require "std.debug".argscheck -- line 1 610 local function caller () -- line 2 611 argscheck ("%s", function () end) -- line 3 612 end -- line 4 613 caller () -- line 5 614 ]], tostring (name), tostring (spec)) 615 end 616 617 f = M.argscheck 618 619 mkmagic = function () return "MAGIC" end 620 wrapped = f ("inner ()", mkmagic) 621 622 _, badarg, badresult = init (M, "", "inner") 623 id = function (...) return unpack {...} end 624 625 - it returns the wrapped function: 626 expect (wrapped).not_to_be (inner) 627 expect (wrapped ()).to_be "MAGIC" 628 - it does not wrap the function when _ARGCHECK is disabled: | 629 script = [[ 630 _DEBUG = false 631 local debug = require "std.debug_init" 632 local argscheck = require "std.debug".argscheck 633 local function inner () return "MAGIC" end 634 local wrapped = argscheck ("inner (?any)", inner) 635 os.exit (wrapped == inner and 0 or 1) 636 ]] 637 expect (luaproc (script)).to_succeed () 638 639 - context when checking zero argument function: 640 - it diagnoses too many arguments: 641 expect (wrapped (false)).to_raise (badarg (1)) 642 - it accepts correct argument types: 643 expect (wrapped ()).to_be "MAGIC" 644 645 - context when checking single argument function: 646 - before: 647 wrapped = f ("inner (#table)", mkmagic) 648 - it diagnoses missing arguments: 649 expect (wrapped ()).to_raise (badarg (1, "non-empty table")) 650 - it diagnoses wrong argument types: 651 expect (wrapped {}).to_raise (badarg (1, "non-empty table", "empty table")) 652 - it diagnoses too many arguments: 653 expect (wrapped ({1}, 2, nop, "", false)).to_raise (badarg (1, 5)) 654 - it accepts correct argument types: 655 expect (wrapped ({1})).to_be "MAGIC" 656 657 - context when checking multi-argument function: 658 - before: 659 wrapped = f ("inner (table, function)", mkmagic) 660 - it diagnoses missing arguments: 661 expect (wrapped ()).to_raise (badarg (1, "table")) 662 expect (wrapped ({})).to_raise (badarg (2, "function")) 663 - it diagnoses wrong argument types: 664 expect (wrapped (false)).to_raise (badarg (1, "table", "boolean")) 665 expect (wrapped ({}, false)).to_raise (badarg (2, "function", "boolean")) 666 - it diagnoses too many arguments: 667 expect (wrapped ({}, nop, false)).to_raise (badarg (3)) 668 - it accepts correct argument types: 669 expect (wrapped ({}, nop)).to_be "MAGIC" 670 671 - context when checking nil argument function: 672 - before: 673 wrapped = f ("inner (?int, string)", mkmagic) 674 - it diagnoses wrong argument types: 675 expect (wrapped (false)).to_raise (badarg (1, "int or nil", "boolean")) 676 expect (wrapped (1, false)).to_raise (badarg (2, "string", "boolean")) 677 expect (wrapped (nil, false)).to_raise (badarg (2, "string", "boolean")) 678 - it diagnoses too many arguments: 679 expect (wrapped (1, "foo", nop)).to_raise (badarg (3)) 680 expect (wrapped (nil, "foo", nop)).to_raise (badarg (3)) 681 - it accepts correct argument types: 682 expect (wrapped (1, "foo")).to_be "MAGIC" 683 expect (wrapped (nil, "foo")).to_be "MAGIC" 684 685 - context when checking optional multi-argument function: 686 - before: 687 wrapped = f ("inner ([int], string)", mkmagic) 688 - it diagnoses missing arguments: 689 expect (wrapped ()).to_raise (badarg (1, "int or string")) 690 expect (wrapped (1)).to_raise (badarg (2, "string")) 691 - it diagnoses wrong argument types: 692 expect (wrapped (false)).to_raise (badarg (1, "int or string", "boolean")) 693 - it diagnoses too many arguments: 694 expect (wrapped (1, "two", nop)).to_raise (badarg (3)) 695 - it accepts correct argument types: 696 expect (wrapped ("two")).to_be "MAGIC" 697 expect (wrapped (1, "two")).to_be "MAGIC" 698 699 - context when checking final optional multi-argument function: 700 - before: 701 wrapped = f ("inner (?any, ?string, [any])", mkmagic) 702 - it diagnoses wrong argument types: 703 expect (wrapped (1, false)).to_raise (badarg (2, "string or nil", "boolean")) 704 expect (wrapped (nil, false)).to_raise (badarg (2, "string or nil", "boolean")) 705 - it diagnoses too many arguments: 706 expect (wrapped (1, "two", 3, false)).to_raise (badarg (4)) 707 expect (wrapped (nil, "two", 3, false)).to_raise (badarg (4)) 708 expect (wrapped (1, nil, 3, false)).to_raise (badarg (4)) 709 expect (wrapped (nil, nil, 3, false)).to_raise (badarg (4)) 710 - it accepts correct argument types: 711 expect (wrapped ()).to_be "MAGIC" 712 expect (wrapped (1)).to_be "MAGIC" 713 expect (wrapped (nil, "two")).to_be "MAGIC" 714 expect (wrapped (1, "two")).to_be "MAGIC" 715 expect (wrapped (nil, nil, 3)).to_be "MAGIC" 716 expect (wrapped (1, nil, 3)).to_be "MAGIC" 717 expect (wrapped (nil, "two", 3)).to_be "MAGIC" 718 expect (wrapped ("one", "two", 3)).to_be "MAGIC" 719 720 - context when checking final ellipsis function: 721 - before: 722 wrapped = f ("inner (string, int...)", mkmagic) 723 - it diagnoses missing arguments: 724 expect (wrapped ()).to_raise (badarg (1, "string")) 725 expect (wrapped ("foo")).to_raise (badarg (2, "int")) 726 - it diagnoses wrong argument types: 727 expect (wrapped (false)).to_raise (badarg (1, "string", "boolean")) 728 expect (wrapped ("foo", false)).to_raise (badarg (2, "int", "boolean")) 729 expect (wrapped ("foo", 1, false)).to_raise (badarg (3, "int", "boolean")) 730 expect (wrapped ("foo", 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, false)). 731 to_raise (badarg (12, "int", "boolean")) 732 - it accepts correct argument types: 733 expect (wrapped ("foo", 1)).to_be "MAGIC" 734 expect (wrapped ("foo", 1, 2)).to_be "MAGIC" 735 expect (wrapped ("foo", 1, 2, 5)).to_be "MAGIC" 736 737 - context when checking optional final parameter: 738 - context with single argument: 739 - before: 740 wrapped = f ("inner ([int])", mkmagic) 741 - it diagnoses wrong argument types: 742 expect (wrapped (false)).to_raise (badarg (1, "int", "boolean")) 743 - it diagnoses too many arguments: 744 expect (wrapped (1, nop)).to_raise (badarg (2)) 745 - it accepts correct argument types: 746 expect (wrapped ()).to_be "MAGIC" 747 expect (wrapped (1)).to_be "MAGIC" 748 - context with trailing ellipsis: 749 - before: 750 wrapped = f ("inner (string, [int]...)", mkmagic) 751 - it diagnoses missing arguments: 752 expect (wrapped ()).to_raise (badarg (1, "string")) 753 - it diagnoses wrong argument types: 754 expect (wrapped (false)).to_raise (badarg (1, "string", "boolean")) 755 expect (wrapped ("foo", false)).to_raise (badarg (2, "int", "boolean")) 756 expect (wrapped ("foo", 1, false)).to_raise (badarg (3, "int", "boolean")) 757 expect (wrapped ("foo", 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, false)). 758 to_raise (badarg (12, "int", "boolean")) 759 - it accepts correct argument types: 760 expect (wrapped ("foo")).to_be "MAGIC" 761 expect (wrapped ("foo", 1)).to_be "MAGIC" 762 expect (wrapped ("foo", 1, 2)).to_be "MAGIC" 763 expect (wrapped ("foo", 1, 2, 5)).to_be "MAGIC" 764 - context with inner ellipsis: 765 - before: 766 wrapped = f ("inner (string, [int...])", mkmagic) 767 - it diagnoses missing arguments: 768 expect (wrapped ()).to_raise (badarg (1, "string")) 769 - it diagnoses wrong argument types: 770 expect (wrapped (false)).to_raise (badarg (1, "string", "boolean")) 771 expect (wrapped ("foo", false)).to_raise (badarg (2, "int", "boolean")) 772 expect (wrapped ("foo", 1, false)).to_raise (badarg (3, "int", "boolean")) 773 expect (wrapped ("foo", 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, false)). 774 to_raise (badarg (12, "int", "boolean")) 775 - it accepts correct argument types: 776 expect (wrapped ("foo")).to_be "MAGIC" 777 expect (wrapped ("foo", 1)).to_be "MAGIC" 778 expect (wrapped ("foo", 1, 2)).to_be "MAGIC" 779 expect (wrapped ("foo", 1, 2, 5)).to_be "MAGIC" 780 781 - context when omitting self type: 782 - before: 783 me = { 784 wrapped = f ("me:inner (string)", mkmagic) 785 } 786 _, badarg, badresult = init (M, "", "me:inner") 787 - it diagnoses missing arguments: 788 expect (me:wrapped ()).to_raise (badarg (1, "string")) 789 - it diagnoses wrong argument types: 790 expect (me:wrapped (false)).to_raise (badarg (1, "string", "boolean")) 791 - it diagnoses too many arguments: 792 expect (me:wrapped ("foo", false)).to_raise (badarg (2)) 793 - it accepts correct argument types: 794 expect (me:wrapped ("foo")).to_be "MAGIC" 795 796 - context with too many args: 797 - before: 798 wrapped = f ("inner ([string], int)", mkmagic) 799 - it diagnoses missing arguments: 800 expect (wrapped ()).to_raise (badarg (1, "string or int")) 801 expect (wrapped ("one")).to_raise (badarg (2, "int")) 802 - it diagnoses wrong argument types: 803 expect (wrapped (false)).to_raise (badarg (1, "string or int", "boolean")) 804 expect (wrapped ("one", false)).to_raise (badarg (2, "int", "boolean")) 805 - it diagnoses too many arguments: 806 expect (wrapped ("one", 2, false)).to_raise (badarg (3)) 807 expect (wrapped (1, false)).to_raise (badarg (2)) 808 - it accepts correct argument types: 809 expect (wrapped (1)).to_be "MAGIC" 810 expect (wrapped ("one", 2)).to_be "MAGIC" 811 812 - context when checking single return value function: 813 - before: | 814 wrapped = f ("inner (?any...) => #table", id) 815 - it diagnoses missing results: 816 expect (wrapped ()).to_raise (badresult (1, "non-empty table")) 817 - it diagnoses wrong result types: 818 expect (wrapped {}). 819 to_raise (badresult (1, "non-empty table", "empty table")) 820 - it diagnoses too many results: 821 expect (wrapped ({1}, 2, nop, "", false)).to_raise (badresult (1, 5)) 822 - it accepts correct results: 823 expect ({wrapped {1}}).to_equal {{1}} 824 825 - context with variant single return value function: 826 - before: 827 wrapped = f ("inner (?any...) => int or nil", id) 828 - it diagnoses wrong result types: 829 expect (wrapped (false)).to_raise (badresult (1, "int or nil", "boolean")) 830 - it diagnoses too many results: 831 expect (wrapped (1, nop)).to_raise (badresult (2)) 832 - it accepts correct result types: 833 expect ({wrapped ()}).to_equal {} 834 expect ({wrapped (1)}).to_equal {1} 835 836 - context when checking multi-return value function: 837 - before: 838 wrapped = f ("inner (?any...) => int, string", id) 839 - it diagnoses missing results: 840 expect (wrapped ()).to_raise (badresult (1, "int")) 841 expect (wrapped (1)).to_raise (badresult (2, "string")) 842 - it diagnoses wrong result types: 843 expect (wrapped (false)).to_raise (badresult (1, "int", "boolean")) 844 expect (wrapped (1, false)).to_raise (badresult (2, "string", "boolean")) 845 - it diagnoses too many results: 846 expect (wrapped (1, "two", false)).to_raise (badresult (3)) 847 - it accepts correct argument types: 848 expect ({wrapped (1, "two")}).to_equal {1, "two"} 849 850 - context when checking nil return specifier: 851 - before: 852 wrapped = f ("inner (?any...) => ?int, string", id) 853 - it diagnoses wrong result types: 854 expect (wrapped (false)).to_raise (badresult (1, "int or nil", "boolean")) 855 expect (wrapped (1, false)).to_raise (badresult (2, "string", "boolean")) 856 expect (wrapped (nil, false)).to_raise (badresult (2, "string", "boolean")) 857 - it diagnoses too many results: 858 expect (wrapped (1, "foo", nop)).to_raise (badresult (3)) 859 expect (wrapped (nil, "foo", nop)).to_raise (badresult (3)) 860 - it accepts correct result types: 861 expect ({wrapped (1, "foo")}).to_equal {1, "foo"} 862 expect ({wrapped (nil, "foo")}).to_equal {[2] = "foo"} 863 864 - context when checking variant multi-return value function: 865 - before: 866 wrapped = f ("inner (?any...) => int, string or string", id) 867 - it diagnoses missing results: 868 expect (wrapped ()).to_raise (badresult (1, "int or string")) 869 expect (wrapped (1)).to_raise (badresult (2, "string")) 870 - it diagnoses wrong result types: 871 expect (wrapped (false)).to_raise (badresult (1, "int or string", "boolean")) 872 - it diagnoses too many results: 873 expect (wrapped (1, "two", nop)).to_raise (badresult (3)) 874 - it accepts correct result types: 875 expect ({wrapped ("two")}).to_equal {"two"} 876 expect ({wrapped (1, "two")}).to_equal {1, "two"} 877 878 - context when checking variant nil,errmsg pattern function: 879 - before: 880 wrapped = f ("inner (?any...) => int, string or nil, string", id) 881 - it diagnoses missing results: 882 expect (wrapped ()).to_raise (badresult (2, "string")) 883 expect (wrapped (1)).to_raise (badresult (2, "string")) 884 - it diagnoses wrong result types: 885 expect (wrapped (false)).to_raise (badresult (1, "int or nil", "boolean")) 886 expect (wrapped (1, false)).to_raise (badresult (2, "string", "boolean")) 887 - it diagnoses too many results: 888 expect (wrapped (1, "two", nop)).to_raise (badresult (3)) 889 expect (wrapped (nil, "errmsg", nop)).to_raise (badresult (3)) 890 - it accepts correct result types: 891 expect ({wrapped (1, "two")}).to_equal {1, "two"} 892 expect ({wrapped (nil, "errmsg")}).to_equal {[2] = "errmsg"} 893 894 - context when checking optional multi-return value function: 895 - before: 896 wrapped = f ("inner (?any...) => [int], string", id) 897 - it diagnoses missing results: 898 expect (wrapped ()).to_raise (badresult (1, "int or string")) 899 expect (wrapped (1)).to_raise (badresult (2, "string")) 900 - it diagnoses wrong result types: 901 expect (wrapped (false)).to_raise (badresult (1, "int or string", "boolean")) 902 - it diagnoses too many results: 903 expect (wrapped (1, "two", nop)).to_raise (badresult (3)) 904 - it accepts correct result types: 905 expect ({wrapped ("two")}).to_equal {"two"} 906 expect ({wrapped (1, "two")}).to_equal {1, "two"} 907 908 - context when checking final optional multi-return value function: 909 - before: 910 wrapped = f ("inner (?any...) => ?any, ?string, [any]", id) 911 - it diagnoses wrong result types: 912 expect (wrapped (1, false)).to_raise (badresult (2, "string or nil", "boolean")) 913 expect (wrapped (nil, false)).to_raise (badresult (2, "string or nil", "boolean")) 914 - it diagnoses too many results: 915 expect (wrapped (1, "two", 3, false)).to_raise (badresult (4)) 916 expect (wrapped (nil, "two", 3, false)).to_raise (badresult (4)) 917 expect (wrapped (1, nil, 3, false)).to_raise (badresult (4)) 918 expect (wrapped (nil, nil, 3, false)).to_raise (badresult (4)) 919 - it accepts correct result types: 920 expect ({wrapped ()}).to_equal {} 921 expect ({wrapped (1)}).to_equal {1} 922 expect ({wrapped (nil, "two")}).to_equal {[2]="two"} 923 expect ({wrapped (1, "two")}).to_equal {1, "two"} 924 expect ({wrapped (nil, nil, 3)}).to_equal {[3]=3} 925 expect ({wrapped (1, nil, 3)}).to_equal {1, [3]=3} 926 expect ({wrapped (nil, "two", 3)}).to_equal {[2]="two", [3]=3} 927 expect ({wrapped ("one", "two", 3)}).to_equal {"one", "two", 3} 928 929 - context when checking optional final result: 930 - context with single result: 931 - before: 932 wrapped = f ("inner (?any...) => [int]", id) 933 - it diagnoses wrong result types: 934 expect (wrapped (false)).to_raise (badresult (1, "int", "boolean")) 935 - it diagnoses too many results: 936 expect (wrapped (1, nop)).to_raise (badresult (2)) 937 - it accepts correct result types: 938 expect ({wrapped ()}).to_equal {} 939 expect ({wrapped (1)}).to_equal {1} 940 - context with trailing ellipsis: 941 - before: 942 wrapped = f ("inner (?any...) => string, [int]...", id) 943 - it diagnoses missing results: 944 expect (wrapped ()).to_raise (badresult (1, "string")) 945 - it diagnoses wrong result types: 946 expect (wrapped (false)).to_raise (badresult (1, "string", "boolean")) 947 expect (wrapped ("foo", false)).to_raise (badresult (2, "int", "boolean")) 948 expect (wrapped ("foo", 1, false)).to_raise (badresult (3, "int", "boolean")) 949 expect (wrapped ("foo", 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, false)). 950 to_raise (badresult (12, "int", "boolean")) 951 - it accepts correct result types: 952 expect ({wrapped ("foo")}).to_equal {"foo"} 953 expect ({wrapped ("foo", 1)}).to_equal {"foo", 1} 954 expect ({wrapped ("foo", 1, 2)}).to_equal {"foo", 1, 2} 955 expect ({wrapped ("foo", 1, 2, 5)}).to_equal {"foo", 1, 2, 5} 956 - context with inner ellipsis: 957 - before: 958 wrapped = f ("inner (?any...) => string, [int...]", id) 959 - it diagnoses missing results: 960 expect (wrapped ()).to_raise (badresult (1, "string")) 961 - it diagnoses wrong result types: 962 expect (wrapped (false)).to_raise (badresult (1, "string", "boolean")) 963 expect (wrapped ("foo", false)).to_raise (badresult (2, "int", "boolean")) 964 expect (wrapped ("foo", 1, false)).to_raise (badresult (3, "int", "boolean")) 965 expect (wrapped ("foo", 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, false)). 966 to_raise (badresult (12, "int", "boolean")) 967 - it accepts correct result types: 968 expect ({wrapped ("foo")}).to_equal {"foo"} 969 expect ({wrapped ("foo", 1)}).to_equal {"foo", 1} 970 expect ({wrapped ("foo", 1, 2)}).to_equal {"foo", 1, 2} 971 expect ({wrapped ("foo", 1, 2, 5)}).to_equal {"foo", 1, 2, 5} 972 973 - context with too many results: 974 - before: 975 wrapped = f ("inner (?any...) => [string], int", id) 976 - it diagnoses missing results: 977 expect (wrapped ()).to_raise (badresult (1, "string or int")) 978 expect (wrapped "one").to_raise (badresult (2, "int")) 979 - it diagnoses wrong result types: 980 expect (wrapped (false)). 981 to_raise (badresult (1, "string or int", "boolean")) 982 expect (wrapped ("one", false)). 983 to_raise (badresult (2, "int", "boolean")) 984 - it diagnoses too many results: 985 expect (wrapped ("one", 2, false)).to_raise (badresult (3)) 986 expect (wrapped (1, false)).to_raise (badresult (2)) 987 - it accepts correct argument types: 988 expect ({wrapped (1)}).to_equal {1} 989 expect ({wrapped ("one", 2)}).to_equal {"one", 2} 990 991 992- describe extramsg_mismatch: 993 - before: 994 f = M.extramsg_mismatch 995 996 - it returns the expected types: 997 expect (f "nil").to_contain "nil expected, " 998 expect (f "bool").to_contain "boolean expected, " 999 expect (f "?bool").to_contain "boolean or nil expected, " 1000 expect (f "string|table").to_contain "string or table expected, " 1001 - it returns expected container types: 1002 expect (f ("table of int", nil, 1)).to_contain "table of ints expected, " 1003 expect (f ("table of int|bool", nil, 1)). 1004 to_contain "table of ints or booleans expected, " 1005 expect (f ("table of int|bool|string", nil, 1)). 1006 to_contain "table of ints, booleans or strings expected, " 1007 expect (f ("table of int|bool|string|table", nil, 1)). 1008 to_contain "table of ints, booleans, strings or tables expected, " 1009 - it returns the actual type: 1010 expect (f ("int")).to_contain ", got no value" 1011 expect (f ("int", false)).to_contain ", got boolean" 1012 expect (f ("int", {})).to_contain ", got empty table" 1013 - it returns table field type: 1014 expect (f ("table of int", nil, 1)).to_contain ", got no value at index 1" 1015 expect (f ("table of int", "two", 2)).to_contain ", got string at index 2" 1016 expect (f ("table of int|bool", "five", 3)).to_contain ", got string at index 3" 1017 1018 1019- describe extramsg_toomany: 1020 - before: 1021 f = M.extramsg_toomany 1022 1023 - it returns the expected thing: 1024 expect (f ("mojo", 1, 2)).to_contain "no more than 1 mojo" 1025 - it uses singular thing when 1 is expected: 1026 expect (f ("argument", 1, 2)).to_contain "no more than 1 argument" 1027 - it uses plural thing otherwise: 1028 expect (f ("thing", 0, 3)).to_contain "no more than 0 things" 1029 expect (f ("result", 2, 3)).to_contain "no more than 2 results" 1030 - it returns the actual count: 1031 expect (f ("bad", 0, 1)).to_contain ", got 1" 1032 expect (f ("bad", 99, 999)).to_contain ", got 999" 1033 1034 1035- context function environments: 1036 - before: 1037 env = { 1038 tostring = function (x) return '"' .. tostring (x) .. '"' end, 1039 } 1040 fn = function (x) return tostring (x) end 1041 ft = setmetatable ({}, { __call = function (_, ...) return fn (...) end }) 1042 1043 - describe getfenv: 1044 - before: 1045 f = M.getfenv 1046 - it returns a table: 1047 expect (type (f (fn))).to_be "table" 1048 - it gets a function execution environment: 1049 M.setfenv (fn, env) 1050 expect (f (fn)).to_be (env) 1051 - it understands functables: 1052 M.setfenv (ft, env) 1053 expect (f (ft)).to_be (env) 1054 1055 - describe setfenv: 1056 - before: 1057 f = M.setfenv 1058 - it returns the passed function: 1059 expect (f (fn, env)).to_be (fn) 1060 - it sets a function execution environment: 1061 f (fn, env) 1062 expect (fn (42)).to_be '"42"' 1063 - it understands functables: 1064 f (ft, env) 1065 expect (fn (5)).to_be '"5"' 1066 1067 1068- describe say: 1069 - before: | 1070 function mkwrap (k, v) 1071 local fmt = "%s" 1072 if type (v) == "string" then fmt = "%q" end 1073 return k, string.format (fmt, require "std".tostring (v)) 1074 end 1075 1076 function mksay (debugp, ...) 1077 return string.format ([[ 1078 _DEBUG = %s 1079 require "std.debug".say (%s) 1080 ]], 1081 require "std".tostring (debugp), 1082 table.concat (require "std.functional".map (mkwrap, {...}), ", ")) 1083 end 1084 1085 f = M.say 1086 1087 - it uses stdlib tostring: 1088 expect (luaproc [[require "std.debug".say {"debugging"}]]). 1089 to_contain_error (require "std".tostring {"debugging"}) 1090 - context when _DEBUG is disabled: 1091 - it does nothing when message level is not set: 1092 expect (luaproc (mksay (false, "nothing to see here"))). 1093 not_to_contain_error "nothing to see here" 1094 - it does nothing when message is set: 1095 expect (luaproc (mksay (false, -999, "nothing to see here"))). 1096 not_to_contain_error "nothing to see here" 1097 expect (luaproc (mksay (false, 0, "nothing to see here"))). 1098 not_to_contain_error "nothing to see here" 1099 expect (luaproc (mksay (false, 1, "nothing to see here"))). 1100 not_to_contain_error "nothing to see here" 1101 expect (luaproc (mksay (false, 2, "nothing to see here"))). 1102 not_to_contain_error "nothing to see here" 1103 expect (luaproc (mksay (false, 999, "nothing to see here"))). 1104 not_to_contain_error "nothing to see here" 1105 - context when _DEBUG is not set: 1106 - it writes to stderr when message level is not set: 1107 expect (luaproc (mksay (nil, "debugging"))). 1108 to_contain_error "debugging" 1109 - it writes to stderr when message level is 1 or lower: 1110 expect (luaproc (mksay (nil, -999, "debugging"))). 1111 to_contain_error "debugging" 1112 expect (luaproc (mksay (nil, 0, "debugging"))). 1113 to_contain_error "debugging" 1114 expect (luaproc (mksay (nil, 1, "debugging"))). 1115 to_contain_error "debugging" 1116 - it does nothing when message level is 2 or higher: 1117 expect (luaproc (mksay (nil, 2, "nothing to see here"))). 1118 not_to_contain_error "nothing to see here" 1119 expect (luaproc (mksay (nil, 999, "nothing to see here"))). 1120 not_to_contain_error "nothing to see here" 1121 - context when _DEBUG is enabled: 1122 - it writes to stderr when message level is not set: 1123 expect (luaproc (mksay (true, "debugging"))). 1124 to_contain_error "debugging" 1125 - it writes to stderr when message level is 1 or lower: 1126 expect (luaproc (mksay (true, -999, "debugging"))). 1127 to_contain_error "debugging" 1128 expect (luaproc (mksay (true, 0, "debugging"))). 1129 to_contain_error "debugging" 1130 expect (luaproc (mksay (true, 1, "debugging"))). 1131 to_contain_error "debugging" 1132 - it does nothing when message level is 2 or higher: 1133 expect (luaproc (mksay (true, 2, "nothing to see here"))). 1134 not_to_contain_error "nothing to see here" 1135 expect (luaproc (mksay (true, 999, "nothing to see here"))). 1136 not_to_contain_error "nothing to see here" 1137 - context when _DEBUG.level is not set: 1138 - it writes to stderr when message level is not set: 1139 expect (luaproc (mksay ({}, "debugging"))). 1140 to_contain_error "debugging" 1141 - it writes to stderr when message level is 1 or lower: 1142 expect (luaproc (mksay ({}, -999, "debugging"))). 1143 to_contain_error "debugging" 1144 expect (luaproc (mksay ({}, 0, "debugging"))). 1145 to_contain_error "debugging" 1146 expect (luaproc (mksay ({}, 1, "debugging"))). 1147 to_contain_error "debugging" 1148 - it does nothing when message level is 2 or higher: 1149 expect (luaproc (mksay ({}, 2, "nothing to see here"))). 1150 not_to_contain_error "nothing to see here" 1151 expect (luaproc (mksay ({}, 999, "nothing to see here"))). 1152 not_to_contain_error "nothing to see here" 1153 - context when _DEBUG.level is specified: 1154 - it writes to stderr when message level is 1 or lower: 1155 expect (luaproc (mksay ({level = 0}, "debugging"))). 1156 to_contain_error "debugging" 1157 expect (luaproc (mksay ({level = 1}, "debugging"))). 1158 to_contain_error "debugging" 1159 expect (luaproc (mksay ({level = 2}, "debugging"))). 1160 to_contain_error "debugging" 1161 - it does nothing when message level is higher than debug level: 1162 expect (luaproc (mksay ({level = 2}, 3, "nothing to see here"))). 1163 not_to_contain_error "nothing to see here" 1164 - it writes to stderr when message level equals debug level: 1165 expect (luaproc (mksay ({level = 2}, 2, "debugging"))). 1166 to_contain_error "debugging" 1167 - it writes to stderr when message level is lower than debug level: 1168 expect (luaproc (mksay ({level = 2}, 1, "debugging"))). 1169 to_contain_error "debugging" 1170 1171 1172- describe trace: 1173 - before: 1174 f = init (M, this_module, "trace") 1175 1176 - it does nothing when _DEBUG is disabled: 1177 expect (luaproc [[ 1178 _DEBUG = false 1179 require "std.debug" 1180 os.exit (0) 1181 ]]).to_succeed_with "" 1182 - it does nothing when _DEBUG is not set: 1183 expect (luaproc [[ 1184 require "std.debug" 1185 os.exit (0) 1186 ]]).to_succeed_with "" 1187 - it does nothing when _DEBUG is enabled: 1188 expect (luaproc [[ 1189 _DEBUG = true 1190 require "std.debug" 1191 os.exit (0) 1192 ]]).to_succeed_with "" 1193 - it enables automatically when _DEBUG.call is set: | 1194 expect (luaproc [[ 1195 _DEBUG = {call = true} 1196 local debug = require "std.debug" 1197 os.exit (1) 1198 ]]).to_fail_while_containing ":3 call exit" 1199 - it is enabled manually with debug.sethook: | 1200 expect (luaproc [[ 1201 local debug = require "std.debug" 1202 debug.sethook (debug.trace, "cr") 1203 os.exit (1) 1204 ]]).to_fail_while_containing ":3 call exit" 1205 - it writes call trace log to standard error: | 1206 expect (luaproc [[ 1207 local debug = require "std.debug" 1208 debug.sethook (debug.trace, "cr") 1209 os.exit (0) 1210 ]]).to_contain_error ":3 call exit" 1211 - it traces lua calls: | 1212 expect (luaproc [[ 1213 local debug = require "std.debug" -- line 1 1214 local function incr (i) return i + 1 end -- line 2 1215 debug.sethook (debug.trace, "cr") -- line 3 1216 os.exit (incr (41)) -- line 4 1217 ]]).to_fail_while_matching ".*:4 call incr <2:.*:4 return incr <2:.*" 1218 - it traces C api calls: | 1219 expect (luaproc [[ 1220 local debug = require "std.debug" 1221 local function incr (i) return i + 1 end 1222 debug.sethook (debug.trace, "cr") 1223 os.exit (incr (41)) 1224 ]]).to_fail_while_matching ".*:4 call exit %[C%]%s$" 1225