diff options
Diffstat (limited to 'testes')
-rw-r--r-- | testes/locals.lua | 48 |
1 files changed, 40 insertions, 8 deletions
diff --git a/testes/locals.lua b/testes/locals.lua index c9c93ccf..8506195e 100644 --- a/testes/locals.lua +++ b/testes/locals.lua | |||
@@ -697,34 +697,66 @@ end | |||
697 | 697 | ||
698 | 698 | ||
699 | do | 699 | do |
700 | -- yielding inside closing metamethods after an error: | 700 | -- yielding inside closing metamethods after an error |
701 | -- not yet implemented; raises an error | ||
702 | 701 | ||
703 | local co = coroutine.wrap(function () | 702 | local co = coroutine.wrap(function () |
704 | 703 | ||
705 | local function foo (err) | 704 | local function foo (err) |
706 | 705 | ||
706 | local z <close> = func2close(function(_, msg) | ||
707 | assert(msg == nil or msg == err + 20) | ||
708 | coroutine.yield("z") | ||
709 | return 100, 200 | ||
710 | end) | ||
711 | |||
712 | local y <close> = func2close(function(_, msg) | ||
713 | -- still gets the original error (if any) | ||
714 | assert(msg == err or (msg == nil and err == 1)) | ||
715 | coroutine.yield("y") | ||
716 | if err then error(err + 20) end -- creates or changes the error | ||
717 | end) | ||
718 | |||
707 | local x <close> = func2close(function(_, msg) | 719 | local x <close> = func2close(function(_, msg) |
708 | assert(msg == err) | 720 | assert(msg == err or (msg == nil and err == 1)) |
709 | coroutine.yield("x") | 721 | coroutine.yield("x") |
710 | return 100, 200 | 722 | return 100, 200 |
711 | end) | 723 | end) |
712 | 724 | ||
713 | if err then error(err) else return 10, 20 end | 725 | if err == 10 then error(err) else return 10, 20 end |
714 | end | 726 | end |
715 | 727 | ||
716 | coroutine.yield(pcall(foo, nil)) -- no error | 728 | coroutine.yield(pcall(foo, nil)) -- no error |
729 | coroutine.yield(pcall(foo, 1)) -- error in __close | ||
717 | return pcall(foo, 10) -- 'foo' will raise an error | 730 | return pcall(foo, 10) -- 'foo' will raise an error |
718 | end) | 731 | end) |
719 | 732 | ||
720 | local a, b = co() | 733 | local a, b = co() -- first foo: no error |
721 | assert(a == "x" and b == nil) -- yields inside 'x'; Ok | 734 | assert(a == "x" and b == nil) -- yields inside 'x'; Ok |
722 | 735 | a, b = co() | |
736 | assert(a == "y" and b == nil) -- yields inside 'y'; Ok | ||
737 | a, b = co() | ||
738 | assert(a == "z" and b == nil) -- yields inside 'z'; Ok | ||
723 | local a, b, c = co() | 739 | local a, b, c = co() |
724 | assert(a and b == 10 and c == 20) -- returns from 'pcall(foo, nil)' | 740 | assert(a and b == 10 and c == 20) -- returns from 'pcall(foo, nil)' |
725 | 741 | ||
726 | local st, msg = co() -- error yielding after an error | 742 | local a, b = co() -- second foo: error in __close |
727 | assert(not st and string.find(msg, "attempt to yield")) | 743 | assert(a == "x" and b == nil) -- yields inside 'x'; Ok |
744 | a, b = co() | ||
745 | assert(a == "y" and b == nil) -- yields inside 'y'; Ok | ||
746 | a, b = co() | ||
747 | assert(a == "z" and b == nil) -- yields inside 'z'; Ok | ||
748 | local st, msg = co() -- reports the error in 'y' | ||
749 | assert(not st and msg == 21) | ||
750 | |||
751 | local a, b = co() -- third foo: error in function body | ||
752 | assert(a == "x" and b == nil) -- yields inside 'x'; Ok | ||
753 | a, b = co() | ||
754 | assert(a == "y" and b == nil) -- yields inside 'y'; Ok | ||
755 | a, b = co() | ||
756 | assert(a == "z" and b == nil) -- yields inside 'z'; Ok | ||
757 | local st, msg = co() -- gets final error | ||
758 | assert(not st and msg == 10 + 20) | ||
759 | |||
728 | end | 760 | end |
729 | 761 | ||
730 | 762 | ||