% $Id: MailboxTest.oz,v 1.2 2006/12/08 07:57:30 leavens Exp leavens $ % Tests for Exercise 2 (Problem 7 in chapter 5 of CTM) \insert 'Mailbox.oz' \insert 'Test.oz' declare %% conditions for testing (guards) fun {Else X} true end fun {Equals Val} fun {$ X} X == Val end end fun {GreaterThan Val} fun {$ X} X > Val end end fun {LessThan Val} fun {$ X} X < Val end end fun {And C1 C2} fun {$ X} {C1 X} andthen {C2 X} end end fun {Or C1 C2} fun {$ X} {C1 X} orelse {C2 X} end end fun {Negate C} fun {$ X} {Not {C X}} end end %% bodies for when guards are true fun {Id X} X end fun {Add Y} fun {$ X} X+Y end end %% Bodies for timeouts, %% note that this is a zero-argument procedure, contrary to the book! fun {Timedout} timedout end {StartTesting 'Mailbox'} MB={Mailbox.new} {StartTesting 'send'} {Mailbox.send MB 541} {StartTesting 'receive'} {Test {Mailbox.receive MB [Else#Id] infinity} '==' 541} {StartTesting 'send and receive of unbound'} {Mailbox.send MB _} {Test {Not {IsDet {Mailbox.receive MB [Else#Id] infinity}}} '==' true} {StartTesting 'Multiple sends and receives'} {Mailbox.send MB 342} {Mailbox.send MB 99} {Test {Mailbox.receive MB [Else#Id] infinity} '==' 342} {Test {Mailbox.receive MB [Else#Id] infinity} '==' 99} {StartTesting 'Receive based on guards'} {Mailbox.send MB 11} {Mailbox.send MB 342} {Mailbox.send MB 99} {Mailbox.send MB 33} {Test {Mailbox.receive MB [{Equals 99}#Id] infinity} '==' 99} {Test {Mailbox.receive MB [Else#Id] infinity} '==' 11} {Test {Mailbox.receive MB [{Equals 33}#Id] infinity} '==' 33} {Test {Mailbox.receive MB [Else#Id] infinity} '==' 342} {StartTesting 'Receive with multiple guards'} {Mailbox.send MB 11} {Mailbox.send MB 342} {Mailbox.send MB 99} {Mailbox.send MB 33} {Mailbox.send MB 10} {Mailbox.send MB 20} {Mailbox.send MB 30} {Test {Mailbox.receive MB [{Equals 99}#Id] infinity} '==' 99} {Test {Mailbox.receive MB [{Equals 99}#Id Else#Id] infinity} '==' 11} {Test {Mailbox.receive MB [{Equals 4}#Id {LessThan 34}#Id Else#Id] infinity} '==' 342} {Test {Mailbox.receive MB [Else#Id Else#{Add 7}] infinity} '==' 33} {Test {Mailbox.receive MB [{Equals 30}#Id {Equals 20}#Id {Equals 10}#{Add 7}] infinity} '==' 17} {Test {Mailbox.receive MB [{Equals 30}#Id {Equals 20}#Id {Equals 10}#{Add 7}] infinity} '==' 20} {Test {Mailbox.receive MB [{Equals 30}#Id {Equals 20}#Id {Equals 10}#{Add 7}] infinity} '==' 30} % Note that receive in Erlang must be done in a process's mailbox, so, % while they can be nested there aren't multiple receive's happening % simultaneously. %% But sends can come from other processes, so can be in threads. {StartTesting 'Receive that blocks, unblocked by send'} thread {Delay 1000} {Mailbox.send MB 99} end thread {Delay 3000} {StartTesting 'sending 5'} {Mailbox.send MB 5} end thread {Delay 6000} {StartTesting 'sending 72'} {Mailbox.send MB 72} end {Test {Mailbox.receive MB [{Equals 99}#Id] infinity} '==' 99} {Test {Mailbox.receive MB [{Equals 72}#Id] infinity} '==' 72} {Test {Mailbox.receive MB [{Equals 5}#Id] infinity} '==' 5} %% Note that timeout procedures (like Timedout) are zero-argument procedures {StartTesting 'Receive with nonzero timeout'} thread {Delay 1000} {Mailbox.send MB 99} end thread {Delay 3000} {StartTesting 'sending 5'} {Mailbox.send MB 5} end thread {Delay 6000} {StartTesting 'sending 72'} {Mailbox.send MB 72} end {Test {Mailbox.receive MB [{Equals 99}#Id] 20#Timedout} '==' timedout} {Test {Mailbox.receive MB [{Equals 72}#Id] 2000#Timedout} '==' timedout} {Test {Mailbox.receive MB [{Equals 5}#Id] infinity} '==' 5} {Test {Mailbox.receive MB [{Equals 72}#Id] 40000#Timedout} '==' 72} {Test {Mailbox.receive MB [{Equals 99}#Id] infinity} '==' 99} {StartTesting 'Receive with zero timeout'} {Mailbox.send MB 27} {Mailbox.send MB 42} {Test {Mailbox.receive MB [{Equals 42}#Id] 0#Timedout} '==' 42} {Test {Mailbox.receive MB [{Equals 27}#Id] 0#Timedout} '==' 27} {Test {Mailbox.receive MB [{Equals 313}#Id] 0#Timedout} '==' timedout} {StartTesting 'All done'}