示例#1
0
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 == ""
示例#2
0
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
示例#3
0
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
示例#4
0
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"])
示例#5
0
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, [])
示例#6
0
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
示例#7
0
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
示例#8
0
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"])
示例#9
0
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
示例#10
0
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",
    ]
示例#11
0
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'"""
    )
示例#12
0
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 == ""
示例#13
0
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
示例#14
0
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
示例#15
0
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
示例#16
0
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
示例#17
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 == ""
示例#18
0
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 == ""
示例#20
0
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 == ""
示例#21
0
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 == ""
示例#22
0
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 == ""
示例#23
0
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:""")
示例#24
0
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
示例#25
0
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",
    ]
示例#26
0
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 == ""
示例#27
0
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: '!' '.'"""
    )
示例#28
0
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 == ""
示例#29
0
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 == ""