def test_errors_without_character_opposite(capsys): s = Shakespeare("Foo. Juliet, a test. Romeo, a test. Macbeth, a test.") s.run_event("[Enter Juliet]") assert s.state.character_by_name("Romeo").value == 0 assert s.state.character_by_name("Macbeth").value == 0 with pytest.raises(ShakespeareRuntimeError) as exc: s.run_sentence("You are as good as a furry animal!", "Juliet") assert "talking to nobody" in str(exc.value).lower() assert ">>You are as good as a furry animal!<<" in str(exc.value) assert exc.value.interpreter == s assert s.state.character_by_name("Romeo").value == 0 assert s.state.character_by_name("Macbeth").value == 0 s.run_event("[Enter Macbeth and Romeo]") assert s.state.character_by_name("Romeo").value == 0 assert s.state.character_by_name("Macbeth").value == 0 with pytest.raises(ShakespeareRuntimeError) as exc: s.run_sentence("You are as good as a furry animal!", "Juliet") assert "ambiguous" in str(exc.value).lower() assert ">>You are as good as a furry animal!<<" in str(exc.value) assert exc.value.interpreter == s assert s.state.character_by_name("Romeo").value == 0 assert s.state.character_by_name("Macbeth").value == 0 captured = capsys.readouterr() assert captured.out == "" assert captured.err == ""
def test_character_must_exist(): s = Shakespeare("Foo.") with pytest.raises(ShakespeareRuntimeError) as exc: s.evaluate_expression("a furry animal", "Juliet") assert "was not initialized" in str(exc.value).lower() assert ">>a furry animal<<" in str(exc.value) assert exc.value.interpreter == s
def test_character_must_be_on_stage(): s = Shakespeare("Foo. Juliet, a test.") with pytest.raises(ShakespeareRuntimeError) as exc: s.evaluate_expression("a furry animal", "Juliet") assert "not on stage" in str(exc.value).lower() assert ">>a furry animal<<" in str(exc.value) assert exc.value.interpreter == s
def test_enter_one(): s = Shakespeare( "Foo. Juliet, a test. Romeo, a test. The Ghost, a test. Demetrius, a test." ) assert_off_stage(s, ["Juliet", "Romeo", "The Ghost", "Demetrius"]) s.run_event("[Enter Juliet]") assert_on_stage(s, ["Juliet"]) assert_off_stage(s, ["Romeo", "The Ghost", "Demetrius"])
def test_enter_four(): s = Shakespeare( "Foo. Juliet, a test. Romeo, a test. The Ghost, a test. Demetrius, a test." ) assert_off_stage(s, ["Juliet", "Romeo", "The Ghost", "Demetrius"]) s.run_event("[Enter Demetrius, The Ghost, Juliet and Romeo]") assert_on_stage(s, ["Demetrius", "The Ghost", "Juliet", "Romeo"]) assert_off_stage(s, [])
def test_adjectives(): s = Shakespeare("Foo. Juliet, a test.") s.run_event("[Enter Juliet]") assert s.evaluate_expression("the big cat", "Juliet") == 2 assert s.evaluate_expression("the big blossoming cat", "Juliet") == 4 assert s.evaluate_expression("the big fine fair cat", "Juliet") == 8 assert s.evaluate_expression("big Microsoft", "Juliet") == -2 assert s.evaluate_expression("big evil Microsoft", "Juliet") == -4 assert s.evaluate_expression("big evil blue Microsoft", "Juliet") == -8
def test_basic_constants(): s = Shakespeare("Foo. Juliet, a test.") s.run_event("[Enter Juliet]") assert s.evaluate_expression("nothing", "Juliet") == 0 assert s.evaluate_expression("a cat", "Juliet") == 1 assert s.evaluate_expression("cat", "Juliet") == 1 assert s.evaluate_expression("the Microsoft", "Juliet") == -1 assert s.evaluate_expression("Microsoft", "Juliet") == -1
def test_errors_on_exit_before_entrance(): s = Shakespeare( "Foo. Juliet, a test. Romeo, a test. The Ghost, a test. Demetrius, a test." ) assert_off_stage(s, ["Juliet", "Romeo", "The Ghost", "Demetrius"]) with pytest.raises(ShakespeareRuntimeError) as exc: s.run_event("[Exit Juliet]") assert "not on stage" in str(exc.value).lower() assert ">>[Exit Juliet]<<" in str(exc.value) assert exc.value.interpreter == s assert_off_stage(s, ["Juliet", "Romeo", "The Ghost", "Demetrius"])
def test_character_name(): s = Shakespeare("Foo. Juliet, a test. Romeo, a test.") s.run_event("[Enter Romeo and Juliet]") s.state.character_by_name("Romeo").value = 895 assert s.evaluate_expression("Romeo", "Juliet") == 895 s.run_event("[Exit Romeo]") assert s.evaluate_expression("Romeo", "Juliet") == 895
def test_correct_characters(): s = Shakespeare("Foo. Juliet, a test. Romeo, a test. The Ghost, a test.") assert sorted(s.state.characters.keys()) == [ "Juliet", "Romeo", "The Ghost", ]
def test_full_error_format_long(): with pytest.raises(ShakespeareParseError) as exc: Shakespeare( textwrap.dedent( """\ Foobar. Baz, a test. Romeo, a test. Act I: The first act. Scene IV: This is a real numeral. [Enter Juliet and Romeo] Juliet: Thou art a pig.""" ), ) assert str(exc.value) == textwrap.dedent( """\ SPL parse error: failed to parse character at line 1 ----- context ----- ∨ Foobar. Baz, a test. Romeo, a test. ∧ Act I: The first act. Scene IV: This is a real numeral. ----- details ----- parsing stack: character, dramatis_persona, dramatis_personae, play full error message: expecting one of: 'Achilles' 'Adonis' 'Adriana' 'Aegeon''Aemilia' 'Agamemnon' 'Agrippa' 'Ajax''Alonso' 'Andromache' 'Angelo''Antiochus' 'Antonio' 'Arthur''Autolycus' 'Balthazar' 'Banquo''Beatrice' 'Benedick' 'Benvolio''Bianca' 'Brabantio' 'Brutus' 'Capulet''Cassandra' 'Cassius' 'Christopher''Cicero' 'Claudio' 'Claudius''Cleopatra' 'Cordelia' 'Cornelius''Cressida' 'Cymberline' 'Demetrius''Desdemona' 'Dionyza' 'Doctor''Dogberry' 'Don' 'Donalbain' 'Dorcas''Duncan' 'Egeus' 'Emilia' 'Escalus''Falstaff' 'Fenton' 'Ferdinand' 'Ford''Fortinbras' 'Francisca' 'Friar''Gertrude' 'Goneril' 'Hamlet' 'Hecate''Hector' 'Helen' 'Helena' 'Hermia''Hermonie' 'Hippolyta' 'Horatio''Imogen' 'Isabella' 'John' 'Julia''Juliet' 'Julius' 'King' 'Lady' 'Lennox''Leonato' 'Luciana' 'Lucio' 'Lychorida''Lysander' 'Macbeth' 'Macduff' 'Malcolm''Mariana' 'Mark' 'Mercutio' 'Miranda''Mistress' 'Montague' 'Mopsa' 'Oberon''Octavia' 'Octavius' 'Olivia' 'Ophelia''Orlando' 'Orsino' 'Othello' 'Page''Pantino' 'Paris' 'Pericles' 'Pinch''Polonius' 'Pompeius' 'Portia' 'Priam''Prince' 'Prospero' 'Proteus' 'Publius''Puck' 'Queen' 'Regan' 'Robin' 'Romeo''Rosalind' 'Sebastian' 'Shallow''Shylock' 'Slender' 'Solinus' 'Stephano''Thaisa' 'The' 'Theseus' 'Thurio''Timon' 'Titania' 'Titus' 'Troilus''Tybalt' 'Ulysses' 'Valentine' 'Venus''Vincentio' 'Viola'""" )
def test_goto_prev(capsys): s = Shakespeare(SAMPLE_PLAY) assert s.current_position == 0 s.step_forward() assert s.current_position == 1 s.step_forward() assert s.current_position == 2 s.step_forward() assert s.current_position == 3 s.run_sentence("Let us return to scene I.", "Juliet") assert s.current_position == 0 captured = capsys.readouterr() assert captured.out == "" assert captured.err == ""
def test_duplicate_act_numbers(capsys): with pytest.raises(ShakespeareRuntimeError) as exc: s = Shakespeare(""" Test. Romeo, a test. Juliet, a test. Act I: Nothing to see here. Scene III: These are not the actors you're looking for. [Enter Romeo and Juliet] Juliet: Are you as good as nothing? Scene I: Still nothing. [A pause] Act I: Nothing strikes back. Scene I: This doesn't matter. [A pause] """) assert "is not unique" in str(exc.value).lower() assert "Act >>I<<: Nothing strikes back." in str(exc.value) assert exc.value.interpreter == None
def test_second_person_pronouns(): s = Shakespeare("Foo. Juliet, a test. Romeo, a test.") s.run_event("[Enter Romeo and Juliet]") s.state.character_by_name("Romeo").value = 895 assert s.evaluate_expression("you", "Juliet") == 895 assert s.evaluate_expression("thou", "Juliet") == 895 assert s.evaluate_expression("thee", "Juliet") == 895 assert s.evaluate_expression("thyself", "Juliet") == 895 assert s.evaluate_expression("yourself", "Juliet") == 895
def test_first_person_pronouns(): s = Shakespeare("Foo. Juliet, a test.") s.run_event("[Enter Juliet]") s.state.character_by_name("Juliet").value = 895 assert s.evaluate_expression("me", "Juliet") == 895 assert s.evaluate_expression("myself", "Juliet") == 895 assert s.evaluate_expression("I", "Juliet") == 895
def test_push(): s = Shakespeare("Foo. Juliet, a test. Romeo, a test.") s.run_event("[Enter Romeo and Juliet]") c = s.state.character_by_name("Juliet") assert c.stack == [] assert c.value == 0 s.run_sentence("Remember a furry animal.", "Romeo") assert c.stack == [2] assert c.value == 0 s.run_sentence("Remember a furry furry animal.", "Romeo") assert c.stack == [2, 4] assert c.value == 0 s.run_sentence("Remember a furry furry furry animal.", "Romeo") assert c.stack == [2, 4, 8] assert c.value == 0
def test_outputs_numbers(capsys): s = Shakespeare("Foo. Juliet, a test. Romeo, a test.") s.run_event("[Enter Romeo and Juliet]") s.state.character_by_name("Romeo").value = 4100 s.run_sentence("Open your heart!", "Juliet") captured = capsys.readouterr() assert captured.out == "4100" assert captured.err == "" s.state.character_by_name("Romeo").value = -5 s.run_sentence("Open your heart!", "Juliet") captured = capsys.readouterr() assert captured.out == "-5" assert captured.err == "" s.state.character_by_name("Romeo").value = 9 s.run_sentence("Open your heart!", "Juliet") captured = capsys.readouterr() assert captured.out == "9" assert captured.err == ""
def test_consumes_trailing_newline(monkeypatch, capsys): monkeypatch.setattr("sys.stdin", StringIO("4257\na")) s = Shakespeare("Foo. Juliet, a test. Romeo, a test.") s.run_event("[Enter Romeo and Juliet]") s.run_sentence("Listen to your heart!", "Juliet") assert s.state.character_by_name("Romeo").value == 4257 assert input() == "a" captured = capsys.readouterr() assert captured.out == "" assert captured.err == "" # Make sure there isn't a '\n' still living in the buffer s.run_sentence("Open your mind!", "Juliet") assert s.state.character_by_name("Romeo").value == -1
def test_eof_character_code(monkeypatch, capsys): monkeypatch.setattr("sys.stdin", StringIO("&")) s = Shakespeare("Foo. Juliet, a test. Romeo, a test.") s.run_event("[Enter Romeo and Juliet]") s.run_sentence("Open your mind!", "Juliet") assert s.state.character_by_name("Romeo").value == 38 s.run_sentence("Open your mind!", "Juliet") assert s.state.character_by_name("Romeo").value == -1 captured = capsys.readouterr() assert captured.out == "" assert captured.err == ""
def test_assign_character(capsys): s = Shakespeare("Foo. Juliet, a test. Romeo, a test.") s.run_event("[Enter Romeo and Juliet]") assert s.state.character_by_name("Romeo").value == 0 s.run_sentence("You are as good as a furry animal!", "Juliet") assert s.state.character_by_name("Romeo").value == 2 s.state.character_by_name("Romeo").value = 0 s.run_sentence("You are a pig!", "Juliet") assert s.state.character_by_name("Romeo").value == -1 captured = capsys.readouterr() assert captured.out == "" assert captured.err == ""
def test_correctly_parses_number(monkeypatch, capsys): monkeypatch.setattr("sys.stdin", StringIO("4257")) s = Shakespeare("Foo. Juliet, a test. Romeo, a test.") s.run_event("[Enter Romeo and Juliet]") s.run_sentence("Listen to your heart!", "Juliet") assert s.state.character_by_name("Romeo").value == 4257 captured = capsys.readouterr() assert captured.out == "" assert captured.err == ""
def test_goto_based_on_numeral_not_order(capsys): s = Shakespeare(""" Test. Romeo, a test. Juliet, a test. Act I: Nothing to see here. Scene III: These are not the actors you're looking for. [Enter Romeo and Juliet] Juliet: Are you as good as nothing? Scene I: Still nothing. [A pause] Scene II: Nothing strikes back. [A pause] """) assert s.current_position == 0 s.step_forward() assert s.current_position == 1 s.run_sentence("Let us return to scene I.", "Juliet") assert s.current_position == 2 s.run_sentence("Let us return to scene III.", "Juliet") assert s.current_position == 0 s.run_sentence("Let us return to scene II.", "Juliet") assert s.current_position == 3 captured = capsys.readouterr() assert captured.out == "" assert captured.err == ""
def test_full_error_format(): s = Shakespeare(ERROR_PLAY) with pytest.raises(ShakespeareRuntimeError) as exc: s.run() assert str(exc.value) == textwrap.dedent("""\ SPL runtime error: Tried to pop from an empty stack. at line 13 ----- context ----- Scene I: A Stage. [Enter Romeo and Juliet] Romeo: You are a pig. >>Recall your mind!<< Recall your mind! [Exeunt] ----- state ----- global boolean = False on stage: Romeo = 0 () Juliet = -1 () off stage:""")
def test_pop(): s = Shakespeare("Foo. Juliet, a test. Romeo, a test.") s.run_event("[Enter Romeo and Juliet]") c = s.state.character_by_name("Juliet") assert c.stack == [] assert c.value == 0 c.stack = [234, 123, 678] s.run_sentence("Recall thy terrible memory of thy imminent death.", "Romeo") assert c.stack == [234, 123] assert c.value == 678 s.run_sentence("Recall thy terrible memory of thy imminent death.", "Romeo") assert c.stack == [234] assert c.value == 123 s.run_sentence("Recall thy terrible memory of thy imminent death.", "Romeo") assert c.stack == [] assert c.value == 234
def test_many_characters(): s = Shakespeare(MANY_CHARACTERS_PLAY) assert sorted(s.state.characters.keys()) == [ "Achilles", "Christopher Sly", "Demetrius", "John of Lancaster", "Juliet", "Mistress Overdone", "Romeo", "Stephano", "The Abbot of Westminster", "The Ghost", "Titania", "Vincentio", ]
def test_interactive_style(monkeypatch, capsys): monkeypatch.setattr("sys.stdin", StringIO("4257\n3211")) s = Shakespeare("Foo. Juliet, a test. Romeo, a test.", input_style="interactive") s.run_event("[Enter Romeo and Juliet]") s.run_sentence("Listen to your heart!", "Juliet") assert s.state.character_by_name("Romeo").value == 4257 captured = capsys.readouterr() assert captured.out == "Taking input number: " assert captured.err == ""
def test_full_error_format_empty(): with pytest.raises(ShakespeareParseError) as exc: Shakespeare("") assert str(exc.value) == textwrap.dedent( """\ SPL parse error: failed to parse play at line 1 ----- context ----- ∨ ∧ ----- details ----- parsing stack: play full error message: expecting one of: '!' '.'""" )
def test_errors_on_eof(monkeypatch, capsys): monkeypatch.setattr("sys.stdin", StringIO("")) s = Shakespeare("Foo. Juliet, a test. Romeo, a test.") s.run_event("[Enter Romeo and Juliet]") with pytest.raises(ShakespeareRuntimeError) as exc: s.run_sentence("Listen to your heart!", "Juliet") assert "end of file" in str(exc.value).lower() assert ">>Listen to your heart!<<" in str(exc.value) assert exc.value.interpreter == s assert s.state.character_by_name("Romeo").value == 0 captured = capsys.readouterr() assert captured.out == "" assert captured.err == ""
def test_complex_expressions(): s = Shakespeare("Foo. Juliet, a test. Romeo, a test.") s.run_event("[Enter Romeo and Juliet]") # (2 * ((4 + 2)^3) * (2 + 4)) % (1 + (2 * (2 + 1))) = 2 first_expression = """ the remainder of the quotient between twice the product of the cube of the sum of my big chihuahua and my big big chihuahua and the sum of my big chihuahua and my big big chihuahua and the sum of my chihuahua and twice the sum of my big chihuahua and my chihuahua """ assert s.evaluate_expression(first_expression, "Juliet") == 2 # (8! - (16^3 - 1)) % (16 - (2 + 1)) = 7 second_expression = """ the remainder of the quotient between the difference between the factorial of my big big big chihuahua and the difference between the cube of my big big big big chihuahua and my chihuahua and the difference between my big big big big chihuahua and the sum of my big chihuahua and my chihuahua """ assert s.evaluate_expression(second_expression, "Juliet") == 7
def test_errors_on_invalid_code(capsys): s = Shakespeare("Foo. Juliet, a test. Romeo, a test.") s.run_event("[Enter Romeo and Juliet]") s.state.character_by_name("Romeo").value = 100000000 with pytest.raises(ShakespeareRuntimeError) as exc: s.run_sentence("Speak your mind!", "Juliet") assert "invalid character code" in str(exc.value).lower() assert ">>Speak your mind!<<" in str(exc.value) assert exc.value.interpreter == s s.state.character_by_name("Romeo").value = -1 with pytest.raises(ShakespeareRuntimeError) as exc: s.run_sentence("Speak your mind!", "Juliet") assert "invalid character code" in str(exc.value).lower() assert ">>Speak your mind!<<" in str(exc.value) assert exc.value.interpreter == s captured = capsys.readouterr() assert captured.out == "" assert captured.err == ""