def test_cleanup(Popen):
    """Test that the spidermonkey processes are terminated during cleanup."""

    process = mock.MagicMock()
    Popen.side_effect = patch_init(process)

    # Make sure we don't already have a cached shell.
    JSShell.cleanup()
    assert JSShell.instance is None
    assert not Popen.called

    process.stdout.readline.return_value = '{}\n'

    get_tree('hello();')

    assert Popen.call_count == 1
    # Clear the reference to `self` in the call history so it can be reaped.
    Popen.reset_mock()

    assert JSShell.instance
    assert not process.terminate.called

    decorator.cleanup()

    assert process.terminate.called
    assert JSShell.instance is None
def test_cleanup(Popen):
    """Test that the spidermonkey processes are terminated during cleanup."""

    process = mock.MagicMock()
    Popen.side_effect = patch_init(process)

    # Make sure we don't already have a cached shell.
    JSShell.cleanup()
    assert JSShell.instance is None
    assert not Popen.called

    process.stdout.readline.return_value = '{}\n'

    get_tree('hello();')

    eq_(Popen.call_count, 1)
    # Clear the reference to `self` in the call history so it can be reaped.
    Popen.reset_mock()

    assert JSShell.instance
    assert not process.terminate.called

    decorator.cleanup()

    assert process.terminate.called
    assert JSShell.instance is None
def test_cleanup_on_error(Popen):
    """Test that the cached shells are removed on IO error."""

    process = mock.MagicMock()
    process.stdout.readline.return_value = '{}'

    Popen.side_effect = patch_init(process)

    # Make sure we don't already have a cached shell.
    JSShell.cleanup()
    assert JSShell.instance is None

    # Success, should have cached shell.
    get_tree('hello();')
    assert Popen.call_count == 1

    assert JSShell.instance
    assert not process.terminate.called

    # Write error. No cached shell.
    process.stdout.readline.reset_mock()
    process.stdin.write.side_effect = IOError

    with pytest.raises(IOError):
        get_tree('hello();')

    # No new processes created, since we had a cached shell from last time.
    assert Popen.call_count == 1
    assert process.stdin.write.called
    assert not process.stdout.readline.called

    # Read error. No cached shell.
    process.stdin.write.reset_mock()
    process.stdin.write.side_effect = None
    process.stdout.readline.side_effect = IOError

    with pytest.raises(IOError):
        get_tree('hello();')

    assert JSShell.instance is None

    # Cached shell should have been removed in the last run. New
    # process should be created.
    assert Popen.call_count == 2
    assert process.stdin.write.called
    assert process.stdout.readline.called

    assert JSShell.instance is None
def test_cleanup_on_error(Popen):
    """Test that the cached shells are removed on IO error."""

    process = mock.MagicMock()
    process.stdout.readline.return_value = '{}'

    Popen.side_effect = patch_init(process)

    # Make sure we don't already have a cached shell.
    JSShell.cleanup()
    assert JSShell.instance is None

    # Success, should have cached shell.
    get_tree('hello();')
    eq_(Popen.call_count, 1)

    assert JSShell.instance
    assert not process.terminate.called

    # Write error. No cached shell.
    process.stdout.readline.reset_mock()
    process.stdin.write.side_effect = IOError

    with assert_raises(IOError):
        get_tree('hello();')

    # No new processes created, since we had a cached shell from last time.
    eq_(Popen.call_count, 1)
    assert process.stdin.write.called
    assert not process.stdout.readline.called

    # Read error. No cached shell.
    process.stdin.write.reset_mock()
    process.stdin.write.side_effect = None
    process.stdout.readline.side_effect = IOError

    with assert_raises(IOError):
        get_tree('hello();')

    assert JSShell.instance is None

    # Cached shell should have been removed in the last run. New
    # process should be created.
    eq_(Popen.call_count, 2)
    assert process.stdin.write.called
    assert process.stdout.readline.called

    assert JSShell.instance is None