def test_config_file_0():
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment, assert_equals
    adjust_environment()

    from reinteract.config_file import _quote_list, _quote, _unquote, _unquote_list
    import tempfile

    def test_quote(s, expected):
        quoted = _quote(s)
        assert_equals(quoted, expected)
        unquoted = _unquote(quoted)
        assert_equals(unquoted, s)

    test_quote(r'', r'""')
    test_quote(r'foo', r'foo')
    test_quote(r'fo"o', r'"fo\"o"')
    test_quote(r'fo o', r'"fo o"')
    test_quote(r'fo\o', r'fo\\o')

    def test_quote_list(l, expected):
        quoted = _quote_list(l)
        assert_equals(quoted, expected)
        unquoted = _unquote_list(quoted)
        assert_equals(unquoted, l)

    test_quote_list(['foo'], 'foo')
    test_quote_list(['foo bar'], '"foo bar"')
    test_quote_list(['foo', 'bar'], 'foo bar')
    test_quote_list(['foo', 'bar baz'], 'foo "bar baz"')

    #--------------------------------------------------------------------------------------
    pass
def test_config_file_0():
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment, assert_equals
    adjust_environment()

    from reinteract.config_file import _quote_list, _quote, _unquote, _unquote_list
    import tempfile

    def test_quote(s, expected):
        quoted = _quote(s)
        assert_equals(quoted, expected)
        unquoted = _unquote(quoted)
        assert_equals(unquoted, s)

    test_quote(r'',  r'""')
    test_quote(r'foo',  r'foo')
    test_quote(r'fo"o', r'"fo\"o"')
    test_quote(r'fo o', r'"fo o"')
    test_quote(r'fo\o', r'fo\\o')

    def test_quote_list(l, expected):
        quoted = _quote_list(l)
        assert_equals(quoted, expected)
        unquoted = _unquote_list(quoted)
        assert_equals(unquoted, l)

    test_quote_list(['foo'], 'foo')
    test_quote_list(['foo bar'], '"foo bar"')
    test_quote_list(['foo', 'bar'], 'foo bar')
    test_quote_list(['foo', 'bar baz'], 'foo "bar baz"')

    #--------------------------------------------------------------------------------------
    pass
Example #3
0
def test_worksheet_2() :
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment
    global_settings = adjust_environment()

    import os
    examplesdir = global_settings.examples_dir
    filename = os.path.join(examplesdir, 'imshow.rws').decode('UTF-8')

    #--------------------------------------------------------------------------------------
    from reinteract.notebook import Notebook
    from reinteract.worksheet import Worksheet
    worksheet = Worksheet( Notebook() )
    worksheet.load(filename)
    worksheet.calculate(wait=True)

    custom_results = []
    from reinteract.chunks import StatementChunk
    from reinteract.custom_result import CustomResult
    for x in worksheet.iterate_chunks() :
        if not isinstance(x,StatementChunk) :
            continue
        if len(x.results) == 0 :
            continue
        arg = x.results[0]
        if isinstance(arg, CustomResult):
           custom_results.append(arg) 
           pass
        pass

    assert len(custom_results) == 2

    #--------------------------------------------------------------------------------------
    pass
Example #4
0
def test_application_state_0():
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment, assert_equals
    adjust_environment()

    from reinteract.application_state import ApplicationState, _section_name
    import tempfile, os

    #--------------------------------------------------------------------------------------
    def test_section_name(path, expected):
        section_name = _section_name(path)
        assert_equals(section_name, expected)

    test_section_name('C:\foo', 'C:\foo')
    test_section_name('foo[]', 'foo%5b%5d')

    #--------------------------------------------------------------------------------------
    f, location = tempfile.mkstemp(".state", "reinteract")
    os.close(f)
    try:
        nb_path = "C:\\Foo\\Bar"

        application_state = ApplicationState(location)
        application_state.notebook_opened(nb_path)
        nb_state = application_state.get_notebook_state(nb_path)
        nb_state.set_open_files([u"foo.rws", u"bar.rws"])
        application_state.flush()

        application_state = ApplicationState(location)

        recent_notebooks = application_state.get_recent_notebooks()
        assert_equals(len(recent_notebooks), 1)
        assert_equals(recent_notebooks[0].path, nb_path)

        nb_state = application_state.get_notebook_state(nb_path)
        assert nb_state.get_last_opened() > 0
        assert_equals(nb_state.get_open_files(), [u"foo.rws", u"bar.rws"])

    finally:
        try:
            os.remove(location)
        except:
            pass
        pass

    #--------------------------------------------------------------------------------------
    pass
Example #5
0
def test_recorded_object_0():
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment, assert_equals
    adjust_environment()

    from reinteract.recorded_object import RecordedObject

    #--------------------------------------------------------------------------------------
    class TestTarget:
        def __init__():
            pass

        def exactargs(self, a, b):
            pass

        def defaultargs(self, a, b=1):
            pass

        def varargs(self, *args):
            pass

        def kwargs(self, **kwargs):
            pass

        pass

    class TestRecorded(RecordedObject):
        pass

    TestRecorded._set_target_class(TestTarget)
    o = TestRecorded()

    # Tests of our argument checking

    def expect_ok(method, *args, **kwargs):
        o.__class__.__dict__[method](o, *args, **kwargs)

    def expect_fail(method, msg, *args, **kwargs):
        try:
            o.__class__.__dict__[method](o, *args, **kwargs)
            raise AssertionError("Expected failure with '%s', got success" %
                                 (msg, ))
        except TypeError, e:
            if str(e) != msg:
                raise AssertionError("Expected failure with '%s', got '%s'" %
                                     (msg, str(e)))
def test_recorded_object_0():
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment, assert_equals
    adjust_environment()

    from reinteract.recorded_object import RecordedObject

    #--------------------------------------------------------------------------------------
    class TestTarget:
        def __init__():
            pass

        def exactargs(self, a, b):
            pass

        def defaultargs(self, a, b=1):
            pass

        def varargs(self, *args):
            pass

        def kwargs(self, **kwargs):
            pass

        pass

    class TestRecorded(RecordedObject):
        pass

    TestRecorded._set_target_class(TestTarget)
    o = TestRecorded()

    # Tests of our argument checking

    def expect_ok(method, *args, **kwargs):
        o.__class__.__dict__[method](o, *args, **kwargs)

    def expect_fail(method, msg, *args, **kwargs):
        try:
            o.__class__.__dict__[method](o, *args, **kwargs)
            raise AssertionError("Expected failure with '%s', got success" % (msg,))
        except TypeError, e:
            if str(e) != msg:
                raise AssertionError("Expected failure with '%s', got '%s'" % (msg, str(e)))
def test_destroyable_0():
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment, assert_equals
    adjust_environment()

    from reinteract.destroyable import Destroyable
    import gobject

    #--------------------------------------------------------------------------------------
    class A(Destroyable, gobject.GObject):
        __gsignals__ = {
            'changed': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ())
        }

    def do_a(*args):
        results.append('a')

    def do_b(*args):
        results.append('b')

    a = A()

    a.connect('changed', do_a)
    handler_id = a.connect('changed', do_b)
    a.disconnect(handler_id)

    results = []
    a.emit('changed')
    assert_equals(results, ['a'])

    a.destroy()

    results = []
    a.emit('changed')
    assert_equals(results, [])

    #--------------------------------------------------------------------------------------
    pass
def test_reunicode_0():
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment, assert_equals
    adjust_environment()

    from reinteract.reunicode import decode, escape_unsafe

    #--------------------------------------------------------------------------------------
    def test_escape_unsafe(u, expected):
        assert_equals(escape_unsafe(u), expected)

    # Embedded NUL is \x00
    test_escape_unsafe(u"a\x00b", u"a\\x00b")
    # Test a tab is left untouched
    test_escape_unsafe(u"\t", u"\t")
    # Non-BMP character (represented as surrogates for UCS-2 python)
    test_escape_unsafe(u"\U00010000", u"\\U00010000")
    # Unpaired surrogate
    test_escape_unsafe(u"\ud800", u"\\ud800")

    def test_decode_escaped(s, expected):
        assert_equals(decode(s, escape=True), expected)

    # Valid UTF-8
    test_decode_escaped(u"\u1234".encode("utf8"), u"\u1234")
    # Invalid UTF-8
    test_decode_escaped("abc\x80\x80abc", u"abc\\x80\\x80abc")
    # Mixture
    test_decode_escaped(u"\u1234".encode("utf8") + "\x80", u"\u1234\\x80")
    # embedded NUL
    test_decode_escaped("\x00", "\\x00")

    # Test a non-UTF-8 encoding
    assert_equals(decode("\xc0", encoding="ISO-8859-1"), u"\u00c0")

    #--------------------------------------------------------------------------------------
    pass
def test_destroyable_0():
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment, assert_equals
    adjust_environment()

    from reinteract.destroyable import Destroyable
    import gobject

    #--------------------------------------------------------------------------------------
    class A(Destroyable, gobject.GObject):
        __gsignals__ = {
                'changed': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ())
        }

    def do_a(*args):
        results.append('a')
    def do_b(*args):
        results.append('b')

    a = A()

    a.connect('changed', do_a)
    handler_id = a.connect('changed', do_b)
    a.disconnect(handler_id)

    results = []
    a.emit('changed')
    assert_equals(results, ['a'])

    a.destroy()

    results = []
    a.emit('changed')
    assert_equals(results, [])

    #--------------------------------------------------------------------------------------
    pass
def test_reunicode_0():
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment, assert_equals
    adjust_environment()

    from reinteract.reunicode import decode, escape_unsafe

    #--------------------------------------------------------------------------------------
    def test_escape_unsafe(u, expected):
        assert_equals(escape_unsafe(u), expected)

    # Embedded NUL is \x00
    test_escape_unsafe(u"a\x00b", u"a\\x00b")
    # Test a tab is left untouched
    test_escape_unsafe(u"\t", u"\t")
    # Non-BMP character (represented as surrogates for UCS-2 python)
    test_escape_unsafe(u"\U00010000", u"\\U00010000")
    # Unpaired surrogate
    test_escape_unsafe(u"\ud800", u"\\ud800")

    def test_decode_escaped(s, expected):
        assert_equals(decode(s, escape=True), expected)

    # Valid UTF-8
    test_decode_escaped(u"\u1234".encode("utf8"), u"\u1234")
    # Invalid UTF-8
    test_decode_escaped("abc\x80\x80abc", u"abc\\x80\\x80abc")
    # Mixture
    test_decode_escaped(u"\u1234".encode("utf8") + "\x80", u"\u1234\\x80")
    # embedded NUL
    test_decode_escaped("\x00", "\\x00")

    # Test a non-UTF-8 encoding
    assert_equals(decode("\xc0", encoding="ISO-8859-1"), u"\u00c0")

    #--------------------------------------------------------------------------------------
    pass
Example #11
0
def test_signals_2():
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment
    global_settings = adjust_environment()

    from reinteract.signals import Signal, Append

    #--------------------------------------------------------------------------------------
    class Container(object):
        def __init__(self):
            pass

        @Append(__init__)
        def __init__(self, *args, **kwargs):
            self._attr = 'dummy'
            self.attr_sig = Signal()
            pass

        @property
        def attr(self):
            return self._attr

        @attr.setter
        def attr(self, the_value):
            self._attr = the_value
            self.attr_sig(self, self._attr)
            pass

        pass

    #--------------------------------------------------------------------------------------
    def listener(the_container, the_attr):
        listener.LOGGER.append(the_attr)
        pass

    listener.LOGGER = []

    #--------------------------------------------------------------------------------------
    a_container = Container()
    a_container.attr_sig.connect(listener)

    a_container.attr = 'funny'

    assert len(listener.LOGGER) == 1

    #--------------------------------------------------------------------------------------
    pass
Example #12
0
def test_signals_2() :
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment
    global_settings = adjust_environment()

    from reinteract.signals import Signal, Append

    #--------------------------------------------------------------------------------------
    class Container( object ) :
        def __init__( self ) :
            pass

        @Append( __init__ )
        def __init__( self, *args, **kwargs ) :
            self._attr = 'dummy'
            self.attr_sig = Signal()
            pass

        @property
        def attr( self ) :
            return self._attr

        @attr.setter
        def attr( self, the_value ) :
            self._attr = the_value
            self.attr_sig( self, self._attr )
            pass

        pass

    #--------------------------------------------------------------------------------------
    def listener( the_container, the_attr ) :
        listener.LOGGER.append( the_attr )
        pass

    listener.LOGGER = []

    #--------------------------------------------------------------------------------------
    a_container = Container()
    a_container.attr_sig.connect( listener )

    a_container.attr = 'funny'

    assert len( listener.LOGGER ) == 1

    #--------------------------------------------------------------------------------------
    pass
Example #13
0
def test_worksheet_1() :
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment
    topdir = adjust_environment()

    from reinteract.notebook import Notebook
    from reinteract.worksheet import Worksheet

    #--------------------------------------------------------------------------------------
    class Logger :
        def __init__( self ) :
            self._log = []
            pass
        def __call__( self, *args ) :
            self._log.append( args )
            pass
        def __len__( self ) :
            return len( self._log )
        def clean( self ) :
            del self._log[ : ]
            pass
        pass

    #--------------------------------------------------------------------------------------
    worksheet = Worksheet( Notebook() )
    a_logger = Logger()

    worksheet.sig_code_modified.connect( lambda *args : a_logger( *args ) )

    #--------------------------------------------------------------------------------------
    a_logger.clean()
    worksheet.begin_user_action()
    worksheet.insert(0, 0, "11\n22\n33")

    assert worksheet.in_user_action() == True
    assert len( a_logger ) == 1

    worksheet.end_user_action()

    #--------------------------------------------------------------------------------------
    pass
Example #14
0
def test_worksheet_0() :
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment
    adjust_environment()

    from reinteract.chunks import StatementChunk, BlankChunk, CommentChunk
    from reinteract.notebook import Notebook, NotebookFile
    from reinteract.worksheet import Worksheet, _debug

    S = StatementChunk
    B = BlankChunk
    C = CommentChunk

    #--------------------------------------------------------------------------------------
    def compare(l1, l2):
        if len(l1) != len(l2):
            return False

        for i in xrange(0, len(l1)):
            e1 = l1[i]
            e2 = l2[i]

            if type(e1) != type(e2) or e1.start != e2.start or e1.end != e2.end:
                return False

        return True

    #--------------------------------------------------------------------------------------
    worksheet = Worksheet(Notebook())

    #--------------------------------------------------------------------------------------
    def expect(expected):
        chunks = [ x for x in worksheet.iterate_chunks() ]
        if not compare(chunks, expected):
            raise AssertionError("\nGot:\n   %s\nExpected:\n   %s" % (chunks, expected))

    #--------------------------------------------------------------------------------------
    def expect_text(expected, start_line=0, start_offset=0, end_line=-1, end_offset=-1):
        text = worksheet.get_text(start_line, start_offset, end_line, end_offset)
        if (text != expected):
            raise AssertionError("\nGot:\n   '%s'\nExpected:\n   '%s'" % (text, expected))

    #--------------------------------------------------------------------------------------
    def expect_doctests(expected, start_line, end_line):
        text = worksheet.get_doctests(start_line, end_line)
        if (text != expected):
            raise AssertionError("\nGot:\n   '%s'\nExpected:\n   '%s'" % (text, expected))

    #--------------------------------------------------------------------------------------
    def expect_results(expected):
        results = [ (x.results if isinstance(x,StatementChunk) else None) for x in worksheet.iterate_chunks() ]
        if (results != expected):
            raise AssertionError("\nGot:\n   '%s'\nExpected:\n   '%s'" % (results, expected))

    #--------------------------------------------------------------------------------------
    def insert(line, offset, text):
        worksheet.insert(line, offset, text)

    #--------------------------------------------------------------------------------------
    def delete(start_line, start_offset, end_line, end_offset):
        worksheet.delete_range(start_line, start_offset, end_line, end_offset)

    #--------------------------------------------------------------------------------------
    def calculate():
        worksheet.calculate(wait=True)

    #--------------------------------------------------------------------------------------
    def clear():
        worksheet.clear()

    #--------------------------------------------------------------------------------------
    def chunk_label(chunk):
        if chunk.end - chunk.start == 1:
            return "[%s]" % chunk.start
        else:
            return "[%s:%s]" % (chunk.start, chunk.end)

    #--------------------------------------------------------------------------------------
    class CI:
        def __init__(self, start, end):
            self.start = start
            self.end = end

        def __eq__(self, other):
            if not isinstance(other, CI):
                return False

            return self.start == other.start and self.end == other.end

        def __repr__(self):
            return "CI(%s, %s)" % (self.start, self.end)

    #--------------------------------------------------------------------------------------
    class CC:
        def __init__(self, start, end, changed_lines):
            self.start = start
            self.end = end
            self.changed_lines = changed_lines

        def __eq__(self, other):
            if not isinstance(other, CC):
                return False

            return self.start == other.start and self.end == other.end and self.changed_lines == other.changed_lines

        def __repr__(self):
            return "CC(%s, %s, %s)" % (self.start, self.end, self.changed_lines)

    #--------------------------------------------------------------------------------------
    class CD:
        def __eq__(self, other):
            if not isinstance(other, CD):
                return False

            return True

        def __repr__(self):
            return "CD()"

    #--------------------------------------------------------------------------------------
    class CSC:
        def __init__(self, start, end):
            self.start = start
            self.end = end

        def __eq__(self, other):
            if not isinstance(other, CSC):
                return False

            return self.start == other.start and self.end == other.end

        def __repr__(self):
            return "CSC(%s, %s)" % (self.start, self.end)

    #--------------------------------------------------------------------------------------
    class CRC:
        def __init__(self, start, end):
            self.start = start
            self.end = end

        def __eq__(self, other):
            if not isinstance(other, CRC):
                return False

            return self.start == other.start and self.end == other.end

        def __repr__(self):
            return "CRC(%s, %s)" % (self.start, self.end)

        pass


    #--------------------------------------------------------------------------------------
    class Logger :
        def __init__( self ) :
            self._log = []
            pass

        def on_chunk_inserted( self, worksheet, chunk ) :
            _debug("...Chunk %s inserted", chunk_label(chunk))
            self._log.append(CI(chunk.start, chunk.end))
            pass

        def on_chunk_changed( self, worksheet, chunk, changed_lines ) :
            _debug("...Chunk %s changed", chunk_label(chunk))
            self._log.append(CC(chunk.start, chunk.end, changed_lines))
            pass

        def on_chunk_deleted( self, worksheet, chunk ) :
            _debug("...Chunk %s deleted", chunk_label(chunk))
            self._log.append(CD())
            pass

        def on_chunk_status_changed( self, worksheet, chunk ) :
            _debug("...Chunk %s status changed", chunk_label(chunk))
            self._log.append(CSC(chunk.start, chunk.end))
            pass

        def on_chunk_results_changed( self, worksheet, chunk ) :
            _debug("...Chunk %s results changed", chunk_label(chunk))
            self._log.append(CRC(chunk.start, chunk.end))
            pass

        def clear_log( self ) :
            self._log = []
            pass

        def expect_log( self, expected ) :
            if self._log != expected:
                raise AssertionError("\nGot:\n   '%s'\nExpected:\n   '%s'" % (log, expected))
            self.clear_log()
            pass
        pass


    #--------------------------------------------------------------------------------------
    a_logger = Logger()
    worksheet.sig_chunk_inserted.connect( a_logger.on_chunk_inserted )
    worksheet.sig_chunk_changed.connect( a_logger.on_chunk_changed )
    worksheet.sig_chunk_deleted.connect( a_logger.on_chunk_deleted )
    worksheet.sig_chunk_status_changed.connect( a_logger.on_chunk_status_changed )
    worksheet.sig_chunk_results_changed.connect( a_logger.on_chunk_results_changed )

    # Insertions
    insert(0, 0, "11\n22\n33")
    expect_text("11\n22\n33")
    expect([S(0,1), S(1,2), S(2,3)])
    insert(0, 1, "a")
    expect_text("1a1\n22\n33")
    expect([S(0,1), S(1,2), S(2,3)])
    insert(1, 1, "a\na")
    expect_text("1a1\n2a\na2\n33")
    expect([S(0,1), S(1,2), S(2,3), S(3,4)])
    insert(1, 0, "bb\n")
    expect_text("1a1\nbb\n2a\na2\n33")
    expect([S(0,1), S(1,2), S(2,3), S(3,4), S(4, 5)])
    insert(4, 3, "\n")
    expect_text("1a1\nbb\n2a\na2\n33\n")
    expect([S(0,1), S(1,2), S(2,3), S(3,4), S(4, 5), B(5, 6)])

    # Deletions
    delete(4, 3, 5, 0)
    expect_text("1a1\nbb\n2a\na2\n33")
    expect([S(0,1), S(1,2), S(2,3), S(3,4), S(4, 5)])
    delete(0, 1, 0, 2)
    expect_text("11\nbb\n2a\na2\n33")
    expect([S(0,1), S(1,2), S(2,3), S(3,4), S(4, 5)])
    delete(0, 0, 1, 0)
    expect_text("bb\n2a\na2\n33")
    expect([S(0,1), S(1,2), S(2,3), S(3,4)])
    delete(1, 1, 2, 1)
    expect_text("bb\n22\n33")
    expect([S(0,1), S(1,2), S(2,3)])
    delete(2, 1, 1, 0)
    expect_text("bb\n3")
    expect([S(0,1), S(1,2)])

    # Test deleting part of a BlankChunk
    clear()
    insert(0, 0, "if True\n:    pass\n    \n")
    delete(2, 4, 3, 0)

    # Check that tracking of changes works properly when there
    # is an insertion or deletion before the change
    clear()
    insert(0, 0, "1\n2")
    worksheet.begin_user_action()
    insert(1, 0, "#")
    insert(0, 0, "0\n")
    worksheet.end_user_action()
    expect_text("0\n1\n#2")
    expect([S(0,1), S(1,2), C(2,3)])
    worksheet.begin_user_action()
    delete(2, 0, 2, 1)
    delete(0, 0, 1, 0)
    worksheet.end_user_action()
    expect([S(0,1), S(1,2)])

    # Basic tokenization of valid python
    clear()
    insert(0, 0, "1\n\n#2\ndef a():\n  3")
    expect([S(0,1), B(1,2), C(2,3), S(3,5)])

    clear()
    expect([B(0,1)])

    # Multiple consecutive blank lines
    clear()
    insert(0, 0, "1")
    insert(0, 1, "\n")
    expect([S(0,1),B(1,2)])
    insert(1, 0, "\n")
    expect([S(0,1),B(1,3)])

    # Continuation lines at the beginning
    clear()
    insert(0, 0, "# Something\n   pass")
    expect([C(0,1), S(1,2)])
    delete(0, 0, 1, 0)
    expect([S(0,1)])

    # Decorators
    clear()
    insert(0, 0, "def foo():\n    return 42")
    expect([S(0,2)])
    insert(0, 0, "@decorated\n")
    expect([S(0,3)])
    insert(0, 0, "@decorated\n")
    expect([S(0,4)])

    # decorator in the middle breaks things up
    insert(3, 0, "@decorated\n")
    expect([S(0,3), S(3,5)])
    delete(3, 0, 4, 0)
    expect([S(0,4)])

    # lonely decorator at the end of a worksheet
    clear()
    insert(0, 0, "@decorated\n# some comment\n")
    expect([S(0,1), C(1,2), B(2,3)])
    insert(2, 0, "def foo():\n    return 42")
    expect([S(0,4)])

    # Calculation
    clear()
    insert(0, 0, "1 + 1")
    calculate()
    expect_results([['2']])

    clear()
    insert(0, 0, "print 1")
    calculate()
    expect_results([['1']])

    clear()
    insert(0, 0, "if True:\n    print 1\n    print 1")
    calculate()
    expect_results([['1', '1']])

    clear()
    insert(0, 0, "a = 1\nb = 2\na + b")
    calculate()
    expect_results([[], [], ['3']])
    delete(1, 4, 1, 5)
    insert(1, 4, "3")
    calculate()
    expect_results([[], [], ['4']])

    #--------------------------------------------------------------------------------------
    #
    # Test out signals and expect_log()
    #
    clear()
    a_logger.clear_log()
    insert(0, 0, "1 + 1")
    a_logger.expect_log([CD(), CI(0,1)])
    calculate()
    a_logger.expect_log([CSC(0,1), CRC(0,1)])

    insert(0, 0, "#")
    a_logger.expect_log([CD(), CI(0,1)])

    # Deleting a chunk with results
    clear()
    insert(0, 0, "1\n2")
    calculate()
    expect([S(0,1),S(1,2)])
    expect_results([['1'],['2']])
    a_logger.clear_log()
    delete(0, 0, 0, 1)
    expect([B(0,1),S(1,2)])
    a_logger.expect_log([CD(), CI(0,1), CSC(1,2)])

    # change a statement into a comment
    clear()
    insert(0, 0, "# a\nb")
    a_logger.clear_log()
    insert(1, 0, "#")
    expect([C(0,2)])
    a_logger.expect_log([CD(), CC(0,2,[1])])

    # Turning a statement into a continuation line
    clear()
    insert(0, 0, "1 \\\n+ 2\n")
    a_logger.clear_log()
    insert(1, 0, " ")
    expect([S(0,2), B(2,3)])
    a_logger.expect_log([CD(), CC(0,2,[1])])

    # And back
    delete(1, 0, 1, 1)
    expect([S(0,1), S(1,2), B(2,3)])
    a_logger.expect_log([CC(0,1,[]),CI(1,2)])

    # Shortening the last chunk in the buffer
    clear()
    insert(0, 0, "def a():\n    x = 1\n    return 1")
    delete(1, 0, 2, 0)
    expect([S(0, 2)])

    # Inserting a statement above a continuation line at the start of the buffer
    clear()
    insert(0, 0, "#def a(x):\n    return x")
    delete(0, 0, 0, 1)
    expect([S(0,2)])

    # Deleting an entire continuation line
    clear()

    insert(0, 0, "for i in (1,2):\n    print i\n    print i + 1\n")
    expect([S(0,3), B(3,4)])
    delete(1, 0, 2, 0)
    expect([S(0,2), B(2,3)])

    # Editing a continuation line, while leaving it a continuation
    clear()

    insert(0, 0, "1\\\n  + 2\\\n  + 3")
    delete(1, 0, 1, 1)
    expect([S(0,3)])

    # Test that changes that substitute text with identical
    # text counts as changes

    # New text
    clear()
    insert(0, 0, "if")
    a_logger.clear_log()
    worksheet.begin_user_action()
    delete(0, 1, 0, 2)
    insert(0, 1, "f")
    worksheet.end_user_action()
    expect([S(0,1)])
    a_logger.expect_log([CC(0,1,[0])])

    # Text from elsewhere in the buffer
    clear()
    insert(0, 0, "if\nif")
    a_logger.clear_log()
    delete(0, 1, 1, 1)
    expect([S(0,1)])
    a_logger.expect_log([CD(), CC(0,1,[0])])

    # Test that commenting out a line marks subsequent lines for recalculation
    clear()

    insert(0, 0, "a = 1\na = 2\na")
    calculate()
    insert(1, 0, "#")
    assert worksheet.get_chunk(2).needs_execute

    # Test that we don't send out '::sig_chunk_deleted' signal for chunks for
    # which we never sent a '::sig_chunk_inserted' signal

    clear()

    insert(0, 0, "[1]")
    a_logger.clear_log()
    worksheet.begin_user_action()
    insert(0, 2, "\n")
    worksheet.rescan()
    insert(1, 0, "    ")
    worksheet.end_user_action()
    a_logger.expect_log([CC(0,2,[0,1])])

    #
    # Undo tests
    #
    clear()

    insert(0, 0, "1")
    worksheet.undo()
    expect_text("")
    worksheet.redo()
    expect_text("1")

    # Undoing insertion of a newline
    clear()

    insert(0, 0, "1 ")
    insert(0, 1, "\n")
    calculate()
    worksheet.undo()
    expect_text("1 ")

    # Test the "pruning" behavior of modifications after undos
    clear()

    insert(0, 0, "1")
    worksheet.undo()
    expect_text("")
    insert(0, 0, "2")
    worksheet.redo() # does nothing
    expect_text("2")
    insert(0, 0, "2\n")

    # Test coalescing consecutive inserts
    clear()

    insert(0, 0, "1")
    insert(0, 1, "2")
    worksheet.undo()
    expect_text("")

    # Test grouping of multiple undos by user actions
    clear()

    insert(0, 0, "1")
    worksheet.begin_user_action()
    delete(0, 0, 0, 1)
    insert(0, 0, "2")
    worksheet.end_user_action()
    worksheet.undo()
    expect_text("1")
    worksheet.redo()
    expect_text("2")

    # Make sure that coalescing doesn't coalesce one user action with
    # only part of another
    clear()

    insert(0, 0, "1")
    worksheet.begin_user_action()
    insert(0, 1, "2")
    delete(0, 0, 0, 1)
    worksheet.end_user_action()
    worksheet.undo()
    expect_text("1")
    worksheet.redo()
    expect_text("2")

    #
    # Tests of get_text()
    #
    clear()
    insert(0, 0, "12\n34\n56")
    expect_text("12\n34\n56", -1, -1, 0, 0)
    expect_text("2\n34\n5", 0, 1, 2, 1)
    expect_text("", -1, -1, -1, -1)
    expect_text("1", 0, 0, 0, 1)
    expect_text("2\n3", 0, 1, 1, 1)
    expect_text("2\n3", 1, 1, 0, 1)

    #
    # Tests of get_doctests()
    #
    clear()
    insert(0, 0, """# A tests of doctests
def a(x):
    return x + 1

a(2)
""")
    calculate()

    expect_doctests("""# A tests of doctests
>>> def a(x):
...     return x + 1

>>> a(2)
3
""", 0, 5)

    expect_doctests(""">>> def a(x):
...     return x + 1
""", 2, 2)

    #
    # Try writing to a file, and reading it back
    #
    import tempfile, os

    clear()
    expect([B(0,1)])

    SAVE_TEST = """a = 1
a
# A comment

b = 2"""

    insert(0, 0, SAVE_TEST)
    calculate()

    handle, fname = tempfile.mkstemp(u".rws", u"reinteract_worksheet")
    os.close(handle)

    try:
        worksheet.save(fname)
        f = open(fname, "r")
        saved = f.read()
        f.close()

        if saved != SAVE_TEST:
            raise AssertionError("Got '%s', expected '%s'", saved, SAVE_TEST)

        worksheet.load(fname)
        calculate()

        expect_text(SAVE_TEST)
        expect([S(0,1), S(1,2), C(2,3), B(3,4), S(4,5)])
        expect_results([[], ['1'], None, None, []])
    finally:
        os.remove(fname)

    clear()
    expect([B(0,1)])
    pass
Example #15
0
def test_signals_0() :
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment
    global_settings = adjust_environment()

    from reinteract.signals import Signal

    #--------------------------------------------------------------------------------------
    class Button:
        def __init__(self):
            # Creating a signal as a member of a class
            self.sigClick = Signal()
            pass
        pass

    #--------------------------------------------------------------------------------------
    class Listener:
        LOGGER = []
        def onClick( self ) :
            Listener.LOGGER.append( "onClick " )
            pass
        def __call__( self ) :
            self.onClick()
            pass
        pass

    #--------------------------------------------------------------------------------------
    # a sample function to connect to the signal
    def listenFunction():
        listenFunction.LOGGER.append( "listenFunction" )
        pass

    listenFunction.LOGGER = []

    #--------------------------------------------------------------------------------------
    # a function that accepts arguments
    def listenWithArgs(text):
        listenWithArgs.LOGGER.append( text )
        pass

    listenWithArgs.LOGGER = []

    #--------------------------------------------------------------------------------------
    def reset_logs() :
        del Listener.LOGGER[ : ]
        del listenFunction.LOGGER[ : ]
        del listenWithArgs.LOGGER[ : ]
        pass
        
    #--------------------------------------------------------------------------------------
    def count() :
        return \
            len( Listener.LOGGER ) + \
            len( listenFunction.LOGGER ) + \
            len( listenWithArgs.LOGGER )
        
    #--------------------------------------------------------------------------------------
    b = Button()
    l = Listener()
    
    #--------------------------------------------------------------------------------------
    # Demonstrating connecting and calling signals
    b.sigClick.connect( l.onClick )

    reset_logs()
    b.sigClick()

    assert len( Listener.LOGGER ) == 1

    #--------------------------------------------------------------------------------------
    # Disconnecting all signals
    b.sigClick.disconnectAll()

    reset_logs()
    b.sigClick()

    assert len( Listener.LOGGER ) == 0

    #--------------------------------------------------------------------------------------
    # connecting multiple functions to a signal
    l2 = Listener()
    b.sigClick.connect( l.onClick )
    b.sigClick.connect( l2.onClick )

    reset_logs()
    b.sigClick()
    
    assert len( Listener.LOGGER ) == 2

    #--------------------------------------------------------------------------------------
    # disconnecting individual functions
    b.sigClick.disconnect( l.onClick )
    b.sigClick.connect( listenFunction )

    reset_logs()
    b.sigClick()
    
    assert len( Listener.LOGGER ) == 1
    assert len( listenFunction.LOGGER ) == 1

    #--------------------------------------------------------------------------------------
    # example with arguments and a local signal
    sig = Signal()
    sig.connect( listenWithArgs )

    reset_logs()
    sig( "Hello, World!" )

    assert len( listenWithArgs.LOGGER ) == 1

    #--------------------------------------------------------------------------------------
    # signals disconnecting 'method slots' automatically
    b.sigClick.disconnectAll()
    b.sigClick.connect( l.onClick )
    b.sigClick.connect( l2.onClick )
    del l2

    reset_logs()
    b.sigClick()
    
    assert len( Listener.LOGGER ) == 1

    #--------------------------------------------------------------------------------------
    # signals disconnecting 'object slots' automatically
    b.sigClick.disconnectAll()
    b.sigClick.connect( l )
    del l

    reset_logs()
    b.sigClick()
    
    assert len( Listener.LOGGER ) == 0

    #--------------------------------------------------------------------------------------
    # signals disconnecting 'lambda slots' automatically
    sig = Signal()
    sig.connect( lambda *args : listenFunction() )

    reset_logs()
    sig( "Hello, World!" )

    assert len( listenFunction.LOGGER ) == 1

    #--------------------------------------------------------------------------------------
    pass
Example #16
0
def test_notebook_0():
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment, assert_equals
    adjust_environment()

    from reinteract.notebook import Notebook

    import copy
    import os, sys
    import tempfile
    import zipfile

    #--------------------------------------------------------------------------------------
    base = tempfile.mkdtemp("", u"shell_buffer")

    def cleanup():
        for root, dirs, files in os.walk(base, topdown=False):
            for name in files:
                os.remove(os.path.join(root, name))
            for name in dirs:
                os.rmdir(os.path.join(root, name))

    def cleanup_pyc():
        # Not absolutely necessary, but makes things less confusing if we do
        # this between tests
        for root, dirs, files in os.walk(base, topdown=False):
            for name in files:
                if name.endswith(".pyc"):
                    os.remove(os.path.join(root, name))

    def write_file(name, contents):
        absname = os.path.join(base, name)
        dirname = os.path.dirname(absname)
        try:
            os.makedirs(dirname)
        except:
            pass

        f = open(absname, "w")
        f.write(contents)
        f.close()

    def write_zipfile(zippath, name, contents):
        abspath = os.path.join(base, zippath)
        dirpath = os.path.dirname(abspath)
        try:
            os.makedirs(dirpath)
        except:
            pass

        if os.path.exists(abspath):
            zip = zipfile.ZipFile(abspath, "a")
        else:
            zip = zipfile.ZipFile(abspath, "w")
        zip.writestr(name, contents)
        zip.close()

    def do_test(import_text, evaluate_text, expected, nb=None):
        if nb is None:
            nb = Notebook(base)

        scope = {}
        nb.setup_globals(scope)

        exec import_text in scope
        result = eval(evaluate_text, scope)

        assert_equals(result, expected)

        cleanup_pyc()

    try:
        write_file("mod1.py", "a = 1")
        write_file("package1/__init__.py", "import os\n__all__ = ['mod2']")
        write_file("package1/mod2.py", "b = 2")
        write_file("package1/mod8.py",
                   "import os\nimport mod2\nf = mod2.b + 1")
        write_file(
            "package1/mod9.py",
            "from __future__ import absolute_import\nfrom . import mod2\ng = mod2.b + 2"
        )
        write_file("package2/__init__.py", "")
        write_file("package2/mod3.py",
                   "import package1.mod2\nc = package1.mod2.b + 1")
        write_file("mod10.py", "def __reinteract_wrap__(obj): return 2")
        write_file("mod11.py", "def __reinteract_wrap__(obj): return 3")

        sys.path.append(os.path.join(base, "ZippedModules.zip"))
        write_zipfile("ZippedModules.zip", "zipmod.py", "d = 4")
        write_zipfile("ZippedModules.zip", "zippackage/__init__.py", "")
        write_zipfile("ZippedModules.zip", "zippackage/mod2.py", "e = 5")

        do_test("import mod1", "mod1.__file__", os.path.join(base, "mod1.py"))

        do_test("import mod1", "mod1.a", 1)
        do_test("import mod1 as m", "m.a", 1)
        do_test("from mod1 import a", "a", 1)
        do_test("from mod1 import a as a2", "a2", 1)

        do_test("import package1.mod2", "package1.mod2.b", 2)
        do_test("import package1.mod2 as m", "m.b", 2)
        do_test("from package1 import mod2", "mod2.b", 2)
        do_test("from package1 import *", "mod2.b", 2)

        do_test("import package1.mod8", "package1.mod8.f", 3)
        do_test("import package1.mod9", "package1.mod9.g", 4)

        # Test loading the same local module a second time in the same notebook
        nb = Notebook(base)
        do_test("import package1.mod2", "package1.mod2.b", 2, nb=nb)
        do_test("import package1.mod2", "package1.mod2.b", 2, nb=nb)

        # http://www.reinteract.org/trac/ticket/5
        do_test("import package2.mod3", "package2.mod3.c", 3)

        do_test("import zipmod", "zipmod.d", 4)
        do_test("import zippackage.mod2", "zippackage.mod2.e", 5)

        # Simple test of __reinteract_wrap__; last has highest priority
        do_test("import mod10\nimport mod11", "__reinteract_wrappers[0](1)", 3)
        do_test("import mod10\nimport mod11", "__reinteract_wrappers[1](1)", 2)

        # Test changing file contents and reloading the module
        nb = Notebook(base)
        write_file("mod4.py", "a = 1")
        do_test("import mod4", "mod4.a", 1, nb=nb)
        write_file("mod4.py", "a = 2")
        nb.reset_module_by_filename(os.path.join(base, "mod4.py"))
        do_test("import mod4", "mod4.a", 2, nb=nb)

        # Test recovering from a syntax error
        nb = Notebook(base)
        write_file("mod4.py", "= 1")
        try:
            do_test("import mod4", "mod4.a", 1, nb=nb)
        except SyntaxError, e:
            pass
        write_file("mod4.py", "a = 1")
        nb.reset_module_by_filename(os.path.join(base, "mod4.py"))
        do_test("import mod4", "mod4.a", 1, nb=nb)

        # Test recovering from a runtime error during import
        nb = Notebook(base)
        write_file("mod5.py", "a = b")
        try:
            do_test("import mod5", "mod5.a", 1, nb=nb)
        except NameError, e:
            pass
def test_shell_buffer() :
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment
    adjust_environment()

    # The tests we include here are tests of the interaction of editing
    # with results. Results don't appear inline in a Worksheet, so these
    # tests have to be here rather than with Worksheet. Almost all other
    # testing is done in Worksheet.

    from reinteract.shell_buffer import ShellBuffer, ADJUST_NONE, _forward_line
    from reinteract.chunks import StatementChunk, BlankChunk, CommentChunk

    from reinteract.notebook import Notebook
    from reinteract import reunicode

    import sys
    from StringIO import StringIO

    buf = ShellBuffer(Notebook())

    def insert(line, offset, text):
        i = buf.get_iter_at_line_offset(line, offset)
        buf.insert_interactive(i, text, True)

    def delete(start_line, start_offset, end_line, end_offset):
        i = buf.get_iter_at_line_offset(start_line, start_offset)
        j = buf.get_iter_at_line_offset(end_line, end_offset)
        buf.delete_interactive(i, j, True)

    def calculate():
        buf.worksheet.calculate(True)

    def clear():
        buf.worksheet.clear()

    def expect(expected):
        si = StringIO()
        i = buf.get_start_iter()
        while True:
            end = i.copy()
            if not end.ends_line():
                end.forward_to_line_end()
            text = reunicode.decode(buf.get_slice(i, end))

            line, _ = buf.iter_to_pos(i, adjust=ADJUST_NONE)
            if line is not None:
                chunk = buf.worksheet.get_chunk(line)
            else:
                chunk = None

            if chunk and isinstance(chunk, StatementChunk):
                if line == chunk.start:
                    si.write(">>> ")
                else:
                    si.write("... ")

            si.write(text)

            if _forward_line(i):
                si.write("\n")
            else:
                break

        result = si.getvalue()
        if not result == expected:
            raise AssertionError("\nGot:\n%s\nExpected:\n%s" % (result, expected))

    # Calculation resulting in result chunks
    insert(0, 0, "1 \\\n + 2\n3\n")
    calculate()
    expect(""">>> 1 \\
...  + 2
3
>>> 3
3
""")

    # Check that splitting a statement with a delete results in the
    # result chunk being moved to the last line of the first half
    delete(1, 0, 1, 1)
    expect(""">>> 1 \\
3
>>> + 2
>>> 3
3
""")

    # Editing a line with an existing error chunk to fix the error
    clear()

    insert(0, 0, "a\na = 2")
    calculate()

    insert(0, 0, "2")
    delete(0, 1, 0, 2)
    calculate()
    expect(""">>> 2
2
>>> a = 2""")

    # Test an attempt to join a ResultChunk onto a previous chunk; should join
    # the line with the following line, moving the result chunk
    clear()

    insert(0, 0, "1\n");
    calculate()
    expect(""">>> 1
1
""")

    delete(0, 1, 1, 0)
    expect(""">>> 1
1""")

    # Test an attempt to join a chunk onto a previous ResultChunk, should move
    # the ResultChunk and do the modification
    clear()
    expect("")

    insert(0, 0, "1\n2\n");
    calculate()
    expect(""">>> 1
1
>>> 2
2
""")
    delete(1, 1, 2, 0)
    expect(""">>> 12
1
""")

    # Test inserting random text inside a result chunk, should ignore
    clear()

    insert(0, 0, "1\n2");
    calculate()
    expect(""">>> 1
1
>>> 2
2""")
    insert(1, 0, "foo")
    expect(""">>> 1
1
>>> 2
2""")


    # Calculation resulting in a multi-line result change
    clear()

    insert(0, 0, "for i in range(0, 3): print i")
    calculate()
    expect(""">>> for i in range(0, 3): print i
0
1
2""")

    # Test deleting a range containing both results and statements
    clear()

    insert(0, 0, "1\n2\n3\n4\n")
    calculate()
    expect(""">>> 1
1
>>> 2
2
>>> 3
3
>>> 4
4
""")

    delete(2, 0, 5, 0)
    expect(""">>> 1
1
>>> 4
4
""")

    # Inserting an entire new statement in the middle
    insert(2, 0, "2.5\n")
    expect(""">>> 1
1
>>> 2.5
>>> 4
4
""")
    calculate()
    expect(""">>> 1
1
>>> 2.5
2.5
>>> 4
4
""")

    # Check that inserting a blank line at the beginning of a statement leaves
    # the result behind
    insert(2, 0, "\n")
    expect(""">>> 1
1

>>> 2.5
2.5
>>> 4
4
""")

    # Test deleting a range including a result and joining two statements
    clear()
    insert(0, 0, "12\n34")
    calculate()
    expect(""">>> 12
12
>>> 34
34""")
    delete(0, 1, 2, 1)
    expect(""">>> 14
12""")

    # Test a deletion that splits the buffer into two (invalid) pieces
    clear()
    insert(0, 0, "try:\n    a = 1\nfinally:\n    print 'Done'")
    calculate()
    expect(""">>> try:
...     a = 1
... finally:
...     print 'Done'
Done""")
    delete(2, 7, 2, 8)
    calculate()
    expect(""">>> try:
...     a = 1
invalid syntax
>>> finally
...     print 'Done'
invalid syntax""")

    # Try an insertion that combines the two pieces and makes them valid
    # again (combining across the error result chunk)
    insert(3, 7, ":")
    calculate()
    expect(""">>> try:
...     a = 1
... finally:
...     print 'Done'
Done""")

    # Test an undo of an insert that caused insertion of result chunks
    clear()

    insert(0, 0, "2\n")
    expect(""">>> 2
""")
    calculate()
    expect(""">>> 2
2
""")
    insert(0, 0, "1\n")
    calculate()
    buf.worksheet.undo()
    expect(""">>> 2
2
""")

    # Test insertion of WarningResult

    clear()

    insert(0, 0, """class A(object):
    def __copy__(self): raise RuntimeError("Can't copy")
    def __repr__(a): return 'A()'
    def foo(x): return x
a = A()
a.foo()""")
    calculate()
    expect(""">>> class A(object):
...     def __copy__(self): raise RuntimeError("Can't copy")
...     def __repr__(a): return 'A()'
...     def foo(x): return x
>>> a = A()
>>> a.foo()
'a' apparently modified, but can't copy it
A()""")
Example #18
0
def test_signals_0():
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment
    global_settings = adjust_environment()

    from reinteract.signals import Signal

    #--------------------------------------------------------------------------------------
    class Button:
        def __init__(self):
            # Creating a signal as a member of a class
            self.sigClick = Signal()
            pass

        pass

    #--------------------------------------------------------------------------------------
    class Listener:
        LOGGER = []

        def onClick(self):
            Listener.LOGGER.append("onClick ")
            pass

        def __call__(self):
            self.onClick()
            pass

        pass

    #--------------------------------------------------------------------------------------
    # a sample function to connect to the signal
    def listenFunction():
        listenFunction.LOGGER.append("listenFunction")
        pass

    listenFunction.LOGGER = []

    #--------------------------------------------------------------------------------------
    # a function that accepts arguments
    def listenWithArgs(text):
        listenWithArgs.LOGGER.append(text)
        pass

    listenWithArgs.LOGGER = []

    #--------------------------------------------------------------------------------------
    def reset_logs():
        del Listener.LOGGER[:]
        del listenFunction.LOGGER[:]
        del listenWithArgs.LOGGER[:]
        pass

    #--------------------------------------------------------------------------------------
    def count():
        return \
            len( Listener.LOGGER ) + \
            len( listenFunction.LOGGER ) + \
            len( listenWithArgs.LOGGER )

    #--------------------------------------------------------------------------------------
    b = Button()
    l = Listener()

    #--------------------------------------------------------------------------------------
    # Demonstrating connecting and calling signals
    b.sigClick.connect(l.onClick)

    reset_logs()
    b.sigClick()

    assert len(Listener.LOGGER) == 1

    #--------------------------------------------------------------------------------------
    # Disconnecting all signals
    b.sigClick.disconnectAll()

    reset_logs()
    b.sigClick()

    assert len(Listener.LOGGER) == 0

    #--------------------------------------------------------------------------------------
    # connecting multiple functions to a signal
    l2 = Listener()
    b.sigClick.connect(l.onClick)
    b.sigClick.connect(l2.onClick)

    reset_logs()
    b.sigClick()

    assert len(Listener.LOGGER) == 2

    #--------------------------------------------------------------------------------------
    # disconnecting individual functions
    b.sigClick.disconnect(l.onClick)
    b.sigClick.connect(listenFunction)

    reset_logs()
    b.sigClick()

    assert len(Listener.LOGGER) == 1
    assert len(listenFunction.LOGGER) == 1

    #--------------------------------------------------------------------------------------
    # example with arguments and a local signal
    sig = Signal()
    sig.connect(listenWithArgs)

    reset_logs()
    sig("Hello, World!")

    assert len(listenWithArgs.LOGGER) == 1

    #--------------------------------------------------------------------------------------
    # signals disconnecting 'method slots' automatically
    b.sigClick.disconnectAll()
    b.sigClick.connect(l.onClick)
    b.sigClick.connect(l2.onClick)
    del l2

    reset_logs()
    b.sigClick()

    assert len(Listener.LOGGER) == 1

    #--------------------------------------------------------------------------------------
    # signals disconnecting 'object slots' automatically
    b.sigClick.disconnectAll()
    b.sigClick.connect(l)
    del l

    reset_logs()
    b.sigClick()

    assert len(Listener.LOGGER) == 0

    #--------------------------------------------------------------------------------------
    # signals disconnecting 'lambda slots' automatically
    sig = Signal()
    sig.connect(lambda *args: listenFunction())

    reset_logs()
    sig("Hello, World!")

    assert len(listenFunction.LOGGER) == 1

    #--------------------------------------------------------------------------------------
    pass
Example #19
0
def test_notebook_0():
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment, assert_equals
    adjust_environment()

    from reinteract.notebook import Notebook

    import copy
    import os, sys
    import tempfile
    import zipfile
    
    #--------------------------------------------------------------------------------------
    base = tempfile.mkdtemp("", u"shell_buffer")
    
    def cleanup():
        for root, dirs, files in os.walk(base, topdown=False):
            for name in files:
                os.remove(os.path.join(root, name))
            for name in dirs:
                os.rmdir(os.path.join(root, name))

    def cleanup_pyc():
        # Not absolutely necessary, but makes things less confusing if we do
        # this between tests
        for root, dirs, files in os.walk(base, topdown=False):
            for name in files:
                if name.endswith(".pyc"):
                    os.remove(os.path.join(root, name))
                
    def write_file(name, contents):
        absname = os.path.join(base, name)
        dirname = os.path.dirname(absname)
        try:
            os.makedirs(dirname)
        except:
            pass

        f = open(absname, "w")
        f.write(contents)
        f.close()

    def write_zipfile(zippath, name, contents):
        abspath = os.path.join(base, zippath)
        dirpath = os.path.dirname(abspath)
        try:
            os.makedirs(dirpath)
        except:
            pass

        if os.path.exists(abspath):
            zip = zipfile.ZipFile(abspath, "a")
        else:
            zip = zipfile.ZipFile(abspath, "w")
        zip.writestr(name, contents)
        zip.close()

    def do_test(import_text, evaluate_text, expected, nb=None):
        if nb is None:
            nb = Notebook(base)

        scope = {}
        nb.setup_globals(scope)
        
        exec import_text in scope
        result = eval(evaluate_text, scope)

        assert_equals(result, expected)

        cleanup_pyc()

    try:
        write_file("mod1.py", "a = 1")
        write_file("package1/__init__.py", "import os\n__all__ = ['mod2']")
        write_file("package1/mod2.py", "b = 2")
        write_file("package1/mod8.py", "import os\nimport mod2\nf = mod2.b + 1")
        write_file("package1/mod9.py", "from __future__ import absolute_import\nfrom . import mod2\ng = mod2.b + 2")
        write_file("package2/__init__.py", "")
        write_file("package2/mod3.py", "import package1.mod2\nc = package1.mod2.b + 1")
        write_file("mod10.py", "def __reinteract_wrap__(obj): return 2")
        write_file("mod11.py", "def __reinteract_wrap__(obj): return 3")

        sys.path.append(os.path.join(base, "ZippedModules.zip"))
        write_zipfile("ZippedModules.zip", "zipmod.py", "d = 4");
        write_zipfile("ZippedModules.zip", "zippackage/__init__.py", "");
        write_zipfile("ZippedModules.zip", "zippackage/mod2.py", "e = 5");

        do_test("import mod1", "mod1.__file__", os.path.join(base, "mod1.py"))

        do_test("import mod1", "mod1.a", 1)
        do_test("import mod1 as m", "m.a", 1)
        do_test("from mod1 import a", "a", 1)
        do_test("from mod1 import a as a2", "a2", 1)

        do_test("import package1.mod2", "package1.mod2.b", 2)
        do_test("import package1.mod2 as m", "m.b", 2)
        do_test("from package1 import mod2", "mod2.b", 2)
        do_test("from package1 import *", "mod2.b", 2)

        do_test("import package1.mod8", "package1.mod8.f", 3);
        do_test("import package1.mod9", "package1.mod9.g", 4);

        # Test loading the same local module a second time in the same notebook
        nb = Notebook(base)
        do_test("import package1.mod2", "package1.mod2.b", 2, nb=nb)
        do_test("import package1.mod2", "package1.mod2.b", 2, nb=nb)

        # http://www.reinteract.org/trac/ticket/5
        do_test("import package2.mod3", "package2.mod3.c", 3)

        do_test("import zipmod", "zipmod.d", 4)
        do_test("import zippackage.mod2", "zippackage.mod2.e", 5)

        # Simple test of __reinteract_wrap__; last has highest priority
        do_test("import mod10\nimport mod11", "__reinteract_wrappers[0](1)", 3)
        do_test("import mod10\nimport mod11", "__reinteract_wrappers[1](1)", 2)

        # Test changing file contents and reloading the module
        nb = Notebook(base)
        write_file("mod4.py", "a = 1")
        do_test("import mod4", "mod4.a", 1, nb=nb)
        write_file("mod4.py", "a = 2")
        nb.reset_module_by_filename(os.path.join(base, "mod4.py"))
        do_test("import mod4", "mod4.a", 2, nb=nb)

        # Test recovering from a syntax error
        nb = Notebook(base)
        write_file("mod4.py", "= 1")
        try:
            do_test("import mod4", "mod4.a", 1, nb=nb)
        except SyntaxError, e:
            pass
        write_file("mod4.py", "a = 1")
        nb.reset_module_by_filename(os.path.join(base, "mod4.py"))
        do_test("import mod4", "mod4.a", 1, nb=nb)

        # Test recovering from a runtime error during import
        nb = Notebook(base)
        write_file("mod5.py", "a = b")
        try:
            do_test("import mod5", "mod5.a", 1, nb=nb)
        except NameError, e:
            pass
Example #20
0
#!/usr/bin/env python

########################################################################
#
# Copyright 2007-2009 Owen Taylor
# Copyright 2008 Kai Willadsen
#
# This file is part of Reinteract and distributed under the terms
# of the BSD license. See the file COPYING in the Reinteract
# distribution for full details.
#
########################################################################

#--------------------------------------------------------------------------------------
if __name__ == "__main__":
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment
    adjust_environment()

    from reinteract.main import main
    main()

    #--------------------------------------------------------------------------------------
    pass

#--------------------------------------------------------------------------------------
def test_statement_0():
    from test_utils import assert_equals, adjust_environment
    adjust_environment()

    from reinteract.statement import Statement

    from reinteract.notebook import Notebook
    nb = Notebook()

    from reinteract.worksheet import Worksheet
    worksheet = Worksheet(nb)

    def expect_result(text, result):
        s = Statement(text, worksheet)
        s.compile()
        s.execute()
        if s.error_message != None :
            raise Exception(s.error_message)
        if isinstance(result, basestring):
            assert_equals(s.results[0], result)
        else:
            assert_equals(s.results, result)
            pass
        pass
    
    # A bare expression should give the repr of the expression
    expect_result("'a'", repr('a'))
    expect_result("1,2", repr((1,2)))

    # Print, on the other hand, gives the string form of the expression, with
    # one result object per output line
    expect_result("print 'a'", 'a')
    expect_result("print 'a', 'b'", ['a b'])
    expect_result("print 'a\\nb'", ['a','b'])

    # Test that we copy a variable before mutating it (when we can detect
    # the mutation)
    s1 = Statement("b = [0]", worksheet)
    s1.compile()
    s1.execute()
    s2 = Statement("b[0] = 1", worksheet, parent=s1)
    s2.compile()
    s2.execute()
    s3 = Statement("b[0]", worksheet, parent=s2)
    s3.compile()
    s3.execute()
    assert_equals(s3.results[0], "1")
    
    s2a = Statement("b[0]", worksheet, parent=s1)
    s2a.compile()
    s2a.execute()
    assert_equals(s2a.results[0], "0")

    # Test __reinteract_wrappers with an unrealistic example
    s1 = Statement("__reinteract_wrappers = [ lambda x: 2 ]", worksheet)
    s1.compile()
    s1.execute()
    s2 = Statement("1", worksheet, parent=s1)
    s2.compile()
    s2.execute()
    assert_equals(s2.results[0], "2")

    # Tests of catching errors
    s1 = Statement("b = ", worksheet)
    assert_equals(s1.compile(), False)
    assert s1.error_message is not None

    s1 = Statement("b", worksheet)
    assert_equals(s1.compile(), True)
    assert_equals(s1.execute(), False)
    assert s1.error_message is not None

    # Tests of 'from __future__ import...'
    s1 = Statement("from __future__ import division", worksheet)
    s1.compile()
    assert_equals(s1.future_features, ['division'])
    s2 = Statement("from __future__ import with_statement", worksheet, parent=s1)
    s2.compile()
    assert_equals(s2.future_features, ['division', 'with_statement'])

    s1 = Statement("import  __future__", worksheet) # just a normal import
    assert_equals(s1.future_features, None)

    # Advanced use of "context manager" protocol
    expect_result('from reinteract.statement import Statement; Statement.get_current() != None', repr(True))

    #--------------------------------------------------------------------------------------
    pass
Example #22
0
def test_shell_buffer():
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment
    adjust_environment()

    # The tests we include here are tests of the interaction of editing
    # with results. Results don't appear inline in a Worksheet, so these
    # tests have to be here rather than with Worksheet. Almost all other
    # testing is done in Worksheet.

    from reinteract.shell_buffer import ShellBuffer, ADJUST_NONE, _forward_line
    from reinteract.chunks import StatementChunk, BlankChunk, CommentChunk

    from reinteract.notebook import Notebook
    from reinteract import reunicode

    import sys
    from StringIO import StringIO

    buf = ShellBuffer(Notebook())

    def insert(line, offset, text):
        i = buf.get_iter_at_line_offset(line, offset)
        buf.insert_interactive(i, text, True)

    def delete(start_line, start_offset, end_line, end_offset):
        i = buf.get_iter_at_line_offset(start_line, start_offset)
        j = buf.get_iter_at_line_offset(end_line, end_offset)
        buf.delete_interactive(i, j, True)

    def calculate():
        buf.worksheet.calculate(True)

    def clear():
        buf.worksheet.clear()

    def expect(expected):
        si = StringIO()
        i = buf.get_start_iter()
        while True:
            end = i.copy()
            if not end.ends_line():
                end.forward_to_line_end()
            text = reunicode.decode(buf.get_slice(i, end))

            line, _ = buf.iter_to_pos(i, adjust=ADJUST_NONE)
            if line is not None:
                chunk = buf.worksheet.get_chunk(line)
            else:
                chunk = None

            if chunk and isinstance(chunk, StatementChunk):
                if line == chunk.start:
                    si.write(">>> ")
                else:
                    si.write("... ")

            si.write(text)

            if _forward_line(i):
                si.write("\n")
            else:
                break

        result = si.getvalue()
        if not result == expected:
            raise AssertionError("\nGot:\n%s\nExpected:\n%s" %
                                 (result, expected))

    # Calculation resulting in result chunks
    insert(0, 0, "1 \\\n + 2\n3\n")
    calculate()
    expect(""">>> 1 \\
...  + 2
3
>>> 3
3
""")

    # Check that splitting a statement with a delete results in the
    # result chunk being moved to the last line of the first half
    delete(1, 0, 1, 1)
    expect(""">>> 1 \\
3
>>> + 2
>>> 3
3
""")

    # Editing a line with an existing error chunk to fix the error
    clear()

    insert(0, 0, "a\na = 2")
    calculate()

    insert(0, 0, "2")
    delete(0, 1, 0, 2)
    calculate()
    expect(""">>> 2
2
>>> a = 2""")

    # Test an attempt to join a ResultChunk onto a previous chunk; should join
    # the line with the following line, moving the result chunk
    clear()

    insert(0, 0, "1\n")
    calculate()
    expect(""">>> 1
1
""")

    delete(0, 1, 1, 0)
    expect(""">>> 1
1""")

    # Test an attempt to join a chunk onto a previous ResultChunk, should move
    # the ResultChunk and do the modification
    clear()
    expect("")

    insert(0, 0, "1\n2\n")
    calculate()
    expect(""">>> 1
1
>>> 2
2
""")
    delete(1, 1, 2, 0)
    expect(""">>> 12
1
""")

    # Test inserting random text inside a result chunk, should ignore
    clear()

    insert(0, 0, "1\n2")
    calculate()
    expect(""">>> 1
1
>>> 2
2""")
    insert(1, 0, "foo")
    expect(""">>> 1
1
>>> 2
2""")

    # Calculation resulting in a multi-line result change
    clear()

    insert(0, 0, "for i in range(0, 3): print i")
    calculate()
    expect(""">>> for i in range(0, 3): print i
0
1
2""")

    # Test deleting a range containing both results and statements
    clear()

    insert(0, 0, "1\n2\n3\n4\n")
    calculate()
    expect(""">>> 1
1
>>> 2
2
>>> 3
3
>>> 4
4
""")

    delete(2, 0, 5, 0)
    expect(""">>> 1
1
>>> 4
4
""")

    # Inserting an entire new statement in the middle
    insert(2, 0, "2.5\n")
    expect(""">>> 1
1
>>> 2.5
>>> 4
4
""")
    calculate()
    expect(""">>> 1
1
>>> 2.5
2.5
>>> 4
4
""")

    # Check that inserting a blank line at the beginning of a statement leaves
    # the result behind
    insert(2, 0, "\n")
    expect(""">>> 1
1

>>> 2.5
2.5
>>> 4
4
""")

    # Test deleting a range including a result and joining two statements
    clear()
    insert(0, 0, "12\n34")
    calculate()
    expect(""">>> 12
12
>>> 34
34""")
    delete(0, 1, 2, 1)
    expect(""">>> 14
12""")

    # Test a deletion that splits the buffer into two (invalid) pieces
    clear()
    insert(0, 0, "try:\n    a = 1\nfinally:\n    print 'Done'")
    calculate()
    expect(""">>> try:
...     a = 1
... finally:
...     print 'Done'
Done""")
    delete(2, 7, 2, 8)
    calculate()
    expect(""">>> try:
...     a = 1
invalid syntax
>>> finally
...     print 'Done'
invalid syntax""")

    # Try an insertion that combines the two pieces and makes them valid
    # again (combining across the error result chunk)
    insert(3, 7, ":")
    calculate()
    expect(""">>> try:
...     a = 1
... finally:
...     print 'Done'
Done""")

    # Test an undo of an insert that caused insertion of result chunks
    clear()

    insert(0, 0, "2\n")
    expect(""">>> 2
""")
    calculate()
    expect(""">>> 2
2
""")
    insert(0, 0, "1\n")
    calculate()
    buf.worksheet.undo()
    expect(""">>> 2
2
""")

    # Test insertion of WarningResult

    clear()

    insert(
        0, 0, """class A(object):
    def __copy__(self): raise RuntimeError("Can't copy")
    def __repr__(a): return 'A()'
    def foo(x): return x
a = A()
a.foo()""")
    calculate()
    expect(""">>> class A(object):
...     def __copy__(self): raise RuntimeError("Can't copy")
...     def __repr__(a): return 'A()'
...     def foo(x): return x
>>> a = A()
>>> a.foo()
'a' apparently modified, but can't copy it
A()""")
Example #23
0
def test_rewrite_0():
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment, assert_equals
    adjust_environment()

    from reinteract.rewrite import Rewriter, UnsupportedSyntaxError
    import copy, re

    def rewrite_and_compile(code, output_func_name=None, future_features=None, print_func_name=None, encoding="utf8"):
        return Rewriter(code, encoding, future_features).rewrite_and_compile(output_func_name, print_func_name)

    #
    # Test that our intercepting of bare expressions to save the output works
    #
    def test_output(code, expected):
        compiled, _ = rewrite_and_compile(code, output_func_name='reinteract_output')
        
        test_args = []
        def set_test_args(*args): test_args[:] = args

        class Builder:
            def __init__(self, arg=None):
                self.arg = arg

            def __enter__(self):
                return self.arg

            def __exit__(self, exception_type, exception_value, traceback):
                pass

        scope = { 'reinteract_output': set_test_args, '__reinteract_builder': Builder }

        exec compiled in scope

        if tuple(test_args) != tuple(expected):
            raise AssertionError("Got '%s', expected '%s'" % (test_args, expected))

    test_output('a=3', ())
    test_output('1', (1,))
    test_output('1,2', (1,2))
    test_output('1;2', (2,))
    test_output('a=3; a', (3,))
    test_output('def x():\n    1\ny = x()', ())
    test_output('class X():\n    1\n    pass\nx = X()', ())

    #
    # Test our build "keyword"
    #
    test_output('build list() as l:\n    l.append(1)', ([1],))
    test_output('build list():\n    pass', ([],))
    test_output('build as l:\n    l = 42', (42,))
    test_output('build:\n    pass', (None,))

    #
    # Test that our intercepting of print works
    #
    def test_print(code, expected):
        compiled, _ = rewrite_and_compile(code, print_func_name='reinteract_print')
        
        test_args = []
        def set_test_args(*args): test_args[:] = args
        scope = { 'reinteract_print': set_test_args }

        exec compiled in scope

        if tuple(test_args) != tuple(expected):
            raise AssertionError("Got '%s', expected '%s'" % (test_args, expected))

    test_print('a=3', ())
    test_print('print 1', (1,))
    test_print('print 1,2', (1,2))
    test_print('print "",', ("",))
    test_print('for i in [0]: print i', (0,))
    test_print('import sys; print >>sys.stderr, "",', ())

    #
    # Test catching possible mutations of variables
    #
    def test_mutated(code, expected, prepare=None, assert_old=None, assert_new=None):
        compiled, mutated = rewrite_and_compile(code)

        #
        # Basic test - check the root and description for the returned list of mutations
        #
        mutated_root_desc = sorted(((root, description) for (root, description, _) in mutated))

        # Extract the root from a description (just take the first word)
        def expand_root_desc(description):
            m = re.match(r"([a-zA-Z_0-9]+)", description)
            return m.group(1), description

        expected_root_desc = sorted((expand_root_desc(x) for x in expected))

        if tuple(mutated_root_desc) != tuple(expected_root_desc):
            raise AssertionError("Got '%s', expected '%s'" % (mutated, expected))

        # More complex test
        #
        #  a) create old scope, execute 'prepare' in it
        #  b) copy old scope, execute each copy statement
        #  c) execute the code
        #  c) run assertion checks in old and new scope

        if prepare:
            old_scope = { '__copy' : copy.copy }
            exec prepare in old_scope
            new_scope = dict(old_scope)

            for _, _, copy_code in mutated:
                exec copy_code in new_scope

            exec compiled in new_scope

            old_ok = eval(assert_old, old_scope)
            if not old_ok:
                raise AssertionError("Old scope assertion '%s' failed" % assert_old)
            new_ok = eval(assert_new, new_scope)
            if not new_ok:
                raise AssertionError("New scope assertion '%s' failed" % assert_new)

    test_mutated('a[0] = 1', ('a',),
                 'a = [2]', 'a[0] == 2', 'a[0] == 1')
    test_mutated('a[0], b[0] = 1, 2', ('a', 'b'),
                 'a,b = [2],[1]', 'a[0],b[0] == 2,1', 'a[0],b[0] == 1,2')
    test_mutated('a[0], _ = 1', ('a'))
    test_mutated('a[0], b[0] = c[0], d[0] = 1, 2', ('a', 'b', 'c', 'd'))
    test_mutated('a[0][1] = 1', ('a', 'a[...]'),
                 'a = [[0,2],1]', 'a[0][1] == 2', 'a[0][1] == 1')

    # This isn't fully right - in the new scope b should be [1], not []
    test_mutated('a[0].append(1)', ('a', 'a[...]'),
                 'b = []; a = [b]',
                 'b == [] and a == [b]', 'b == [] and a == [[1]]')

    test_mutated('a += 1', ('a',))
    test_mutated('a[0] += 1', ('a', 'a[...]'))

    prepare = """
class A:
    def __init__(self):
        self.b = 1
    def addmul(self, x,y):
        self.b += x * y
    def get_a(self):
        return self.a
    pass
a = A()
a.a = A()
"""

    test_mutated('a.b = 2', ('a',),
                 prepare, 'a.b == 1', 'a.b == 2')
    test_mutated('a.b = 2', ('a',),
                 prepare, 'a.b == 1', 'a.b == 2')
    test_mutated('a.a.b = 2', ('a','a.a'),
                 prepare, 'a.a.b == 1', 'a.a.b == 2')
    test_mutated('a.a.b += 1', ('a','a.a','a.a.b'),
                 prepare, 'a.a.b == 1', 'a.a.b == 2')

    test_mutated('a.addmul(1,2)', ('a',),
                 prepare, 'a.b == 1', 'a.b == 3')
    test_mutated('a.a.addmul(1,2)', ('a', 'a.a'),
                 prepare, 'a.a.b == 1', 'a.a.b == 3')

    # We exempt some methods as being most likely getters.
    test_mutated('a.get_a()', ())
    test_mutated('a.hasA()', ())
    test_mutated('a.isa()', ())

    # These don't actually work properly since we don't know to copy a.a
    # So we just check the descriptions and not the execution
    #
    test_mutated('a.get_a().b = 2', ('a.get_a(...)',))
    test_mutated('a.get_a().a.b = 2', ('a.get_a(...).a',))

    # Tests of skipping mutations when the mutations are actually of
    # local variables
    test_mutated('def f(x):\n    x[1] = 2\n', ())
    test_mutated('def f(y):\n    x = [1]\n    x[1] = 2\n', ())
    test_mutated('def f(x):\n    def g(x):\n        pass', ())
    test_mutated('def f(x):\n    import g', ())
    test_mutated('def f(x):\n    from m import g', ())
    test_mutated('def f(x):\n    from m import g as h\n    h[2] = 3', ())
    test_mutated('class X:\n    x = [1]\n    x[1] = 2\n', ())
    test_mutated('def f(x):\n    class C:\n        pass', ())
    test_mutated('def f((x,)):\n    x[1] = 2\n', ())
    test_mutated('def f(((x,),)):\n    x[1] = 2\n', ())

    # But these are global mutations
    test_mutated('class X:\n    x[1] = 2\n', ('x'))
    test_mutated('class X:\n    global x\n    x[1] = 2\n    x = [1]\n', ('x'))

    # Trying to mutate a global variable inside a function is an error

    def test_unsupported_syntax(code):
        caught_exception = False
        try:
            rewrite_and_compile(code)
        except UnsupportedSyntaxError, e:
            caught_exception = True
        assert_equals(caught_exception, True)
########################################################################
#
# Copyright 2008-2009 Owen Taylor
#
# This file is part of Reinteract and distributed under the terms
# of the BSD license. See the file COPYING in the Reinteract
# distribution for full details.
#
########################################################################


#--------------------------------------------------------------------------------------
if __name__ == "__main__":
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment
    adjust_environment()

    from reinteract.notebook import Notebook
    from reinteract.worksheet_editor import WorksheetEditor
    an_editor = WorksheetEditor(Notebook())

    import gtk
    window = gtk.Window(gtk.WINDOW_TOPLEVEL)
    window.set_resizable(True)  
    window.connect("destroy", lambda widget : gtk.main_quit())
    window.set_title(__file__)
    window.set_border_width(0)
    window.resize(500, 500)
    
    window.add(an_editor.widget)
    window.show()
Example #25
0
########################################################################
#
# Copyright 2007-2011 Owen Taylor
#
# This file is part of Reinteract and distributed under the terms
# of the BSD license. See the file COPYING in the Reinteract
# distribution for full details.
#
########################################################################


#--------------------------------------------------------------------------------------
if __name__ == "__main__":
    #--------------------------------------------------------------------------------------
    from test_utils import adjust_environment
    global_settings = adjust_environment()

    import os
    examplesdir = global_settings.examples_dir
    filename = os.path.join(examplesdir, 'imshow.rws').decode('UTF-8')

    import gtk
    window = gtk.Window(gtk.WINDOW_TOPLEVEL)
    window.set_resizable(True)  
    window.connect("destroy", lambda widget : gtk.main_quit())
    window.set_title(__file__)
    window.set_border_width(0)
    window.resize(500, 500)
    
    vbox = gtk.VBox(False, 0)
    window.add(vbox)
def test_thread_executor_0() :
    from test_utils import adjust_environment, assert_equals
    global_settings = adjust_environment()

    from reinteract.notebook import Notebook
    from reinteract.statement import Statement
    from reinteract.worksheet import Worksheet

    import threading
    import time

    from reinteract.thread_executor import ThreadExecutor, _pthread_kill, eventLoop

    failed = False

    notebook = Notebook()
    worksheet = Worksheet(notebook)

    def test_execute(statements):
        executor = ThreadExecutor()
        loop = executor.event_loop

        for s, expected_state, expected_results in statements:
            statement = Statement(s, worksheet)
            statement._expected_state = expected_state
            statement._expected_results = expected_results
            statement._got_executing = False
            executor.add_statement(statement)

        def on_statement_executing(executor, statement):
            if hasattr(statement, '_got_state'):
                statement._out_of_order = True
            statement._got_executing = True

        def on_statement_complete(executor, statement):
            statement._got_state = statement.state
            statement._got_results = statement.results
            statement._out_of_order = False

        def on_complete(executor):
            loop.quit()

        def interrupt():
            executor.interrupt()

        global timed_out
        timed_out = False
        def timeout():
            global timed_out
            timed_out = True
            loop.quit()

        executor.sig_statement_executing.connect(on_statement_executing)
        executor.sig_statement_complete.connect(on_statement_complete)
        executor.sig_complete.connect(on_complete)

        if executor.compile():
            executor.execute()

            interrupt_source = threading.Timer(0.5, interrupt)
            interrupt_source.start()

            timeout_source = threading.Timer(1.0, timeout)
            timeout_source.start()
            loop.run()
            if timed_out:
                raise AssertionError("Interrupting ThreadExecutor failed")

            interrupt_source.cancel()
            timeout_source.cancel()

        for s in executor.statements:
            assert_equals(s._got_state, s._expected_state)
            assert_equals(s._got_results, s._expected_results)
            if s._out_of_order:
                raise AssertionError("ThreadExecutor sent 'sig_statement_executing' after 'sig_statement_complete'")
            if s._expected_state == Statement.INTERRUPTED and not s._got_executing:
                raise AssertionError("ThreadExecutor did not send 'sig_statement_executing' within timeout")

    test_execute(
        [
            ("a = 1", Statement.COMPILE_SUCCESS, None),
            ("a =", Statement.COMPILE_ERROR, None)
        ])

    test_execute(
        [
            ("a = 1", Statement.EXECUTE_SUCCESS, []),
            ("a", Statement.EXECUTE_SUCCESS, ['1'])
        ])

    test_execute(
        [
            ("a = 1", Statement.EXECUTE_SUCCESS, []),
            ("b", Statement.EXECUTE_ERROR, None),
            ("c = 2", Statement.COMPILE_SUCCESS, None)
        ])

    # Test interrupting straight python code
    test_execute(
        [
            ("y = 1", Statement.EXECUTE_SUCCESS, []),
            ("for x in xrange(0,100000000):\n    y = y * 2\n    if y > 100: y = 1", Statement.INTERRUPTED, None),
            ("z = 1", Statement.COMPILE_SUCCESS, None)
        ])

    # Test interrupting a blocking syscall, if support on this platform
    if _pthread_kill is not None:
        test_execute(
            [
                ("import sys", Statement.EXECUTE_SUCCESS, []),
                ("sys.stdin.readline()", Statement.INTERRUPTED, None),
                ("z = 1", Statement.COMPILE_SUCCESS, None)
            ])
        pass
Example #27
0
def test_thread_executor_0():
    from test_utils import adjust_environment, assert_equals
    global_settings = adjust_environment()

    from reinteract.notebook import Notebook
    from reinteract.statement import Statement
    from reinteract.worksheet import Worksheet

    import threading
    import time

    from reinteract.thread_executor import ThreadExecutor, _pthread_kill, eventLoop

    failed = False

    notebook = Notebook()
    worksheet = Worksheet(notebook)

    def test_execute(statements):
        executor = ThreadExecutor()
        loop = executor.event_loop

        for s, expected_state, expected_results in statements:
            statement = Statement(s, worksheet)
            statement._expected_state = expected_state
            statement._expected_results = expected_results
            statement._got_executing = False
            executor.add_statement(statement)

        def on_statement_executing(executor, statement):
            if hasattr(statement, '_got_state'):
                statement._out_of_order = True
            statement._got_executing = True

        def on_statement_complete(executor, statement):
            statement._got_state = statement.state
            statement._got_results = statement.results
            statement._out_of_order = False

        def on_complete(executor):
            loop.quit()

        def interrupt():
            executor.interrupt()

        global timed_out
        timed_out = False

        def timeout():
            global timed_out
            timed_out = True
            loop.quit()

        executor.sig_statement_executing.connect(on_statement_executing)
        executor.sig_statement_complete.connect(on_statement_complete)
        executor.sig_complete.connect(on_complete)

        if executor.compile():
            executor.execute()

            interrupt_source = threading.Timer(0.5, interrupt)
            interrupt_source.start()

            timeout_source = threading.Timer(1.0, timeout)
            timeout_source.start()
            loop.run()
            if timed_out:
                raise AssertionError("Interrupting ThreadExecutor failed")

            interrupt_source.cancel()
            timeout_source.cancel()

        for s in executor.statements:
            assert_equals(s._got_state, s._expected_state)
            assert_equals(s._got_results, s._expected_results)
            if s._out_of_order:
                raise AssertionError(
                    "ThreadExecutor sent 'sig_statement_executing' after 'sig_statement_complete'"
                )
            if s._expected_state == Statement.INTERRUPTED and not s._got_executing:
                raise AssertionError(
                    "ThreadExecutor did not send 'sig_statement_executing' within timeout"
                )

    test_execute([("a = 1", Statement.COMPILE_SUCCESS, None),
                  ("a =", Statement.COMPILE_ERROR, None)])

    test_execute([("a = 1", Statement.EXECUTE_SUCCESS, []),
                  ("a", Statement.EXECUTE_SUCCESS, ['1'])])

    test_execute([("a = 1", Statement.EXECUTE_SUCCESS, []),
                  ("b", Statement.EXECUTE_ERROR, None),
                  ("c = 2", Statement.COMPILE_SUCCESS, None)])

    # Test interrupting straight python code
    test_execute([
        ("y = 1", Statement.EXECUTE_SUCCESS, []),
        ("for x in xrange(0,100000000):\n    y = y * 2\n    if y > 100: y = 1",
         Statement.INTERRUPTED, None),
        ("z = 1", Statement.COMPILE_SUCCESS, None)
    ])

    # Test interrupting a blocking syscall, if support on this platform
    if _pthread_kill is not None:
        test_execute([("import sys", Statement.EXECUTE_SUCCESS, []),
                      ("sys.stdin.readline()", Statement.INTERRUPTED, None),
                      ("z = 1", Statement.COMPILE_SUCCESS, None)])
        pass
def test_statement_0():
    from test_utils import assert_equals, adjust_environment
    adjust_environment()

    from reinteract.statement import Statement

    from reinteract.notebook import Notebook
    nb = Notebook()

    from reinteract.worksheet import Worksheet
    worksheet = Worksheet(nb)

    def expect_result(text, result):
        s = Statement(text, worksheet)
        s.compile()
        s.execute()
        if s.error_message != None:
            raise Exception(s.error_message)
        if isinstance(result, basestring):
            assert_equals(s.results[0], result)
        else:
            assert_equals(s.results, result)
            pass
        pass

    # A bare expression should give the repr of the expression
    expect_result("'a'", repr('a'))
    expect_result("1,2", repr((1, 2)))

    # Print, on the other hand, gives the string form of the expression, with
    # one result object per output line
    expect_result("print 'a'", 'a')
    expect_result("print 'a', 'b'", ['a b'])
    expect_result("print 'a\\nb'", ['a', 'b'])

    # Test that we copy a variable before mutating it (when we can detect
    # the mutation)
    s1 = Statement("b = [0]", worksheet)
    s1.compile()
    s1.execute()
    s2 = Statement("b[0] = 1", worksheet, parent=s1)
    s2.compile()
    s2.execute()
    s3 = Statement("b[0]", worksheet, parent=s2)
    s3.compile()
    s3.execute()
    assert_equals(s3.results[0], "1")

    s2a = Statement("b[0]", worksheet, parent=s1)
    s2a.compile()
    s2a.execute()
    assert_equals(s2a.results[0], "0")

    # Test __reinteract_wrappers with an unrealistic example
    s1 = Statement("__reinteract_wrappers = [ lambda x: 2 ]", worksheet)
    s1.compile()
    s1.execute()
    s2 = Statement("1", worksheet, parent=s1)
    s2.compile()
    s2.execute()
    assert_equals(s2.results[0], "2")

    # Tests of catching errors
    s1 = Statement("b = ", worksheet)
    assert_equals(s1.compile(), False)
    assert s1.error_message is not None

    s1 = Statement("b", worksheet)
    assert_equals(s1.compile(), True)
    assert_equals(s1.execute(), False)
    assert s1.error_message is not None

    # Tests of 'from __future__ import...'
    s1 = Statement("from __future__ import division", worksheet)
    s1.compile()
    assert_equals(s1.future_features, ['division'])
    s2 = Statement("from __future__ import with_statement",
                   worksheet,
                   parent=s1)
    s2.compile()
    assert_equals(s2.future_features, ['division', 'with_statement'])

    s1 = Statement("import  __future__", worksheet)  # just a normal import
    assert_equals(s1.future_features, None)

    # Advanced use of "context manager" protocol
    expect_result(
        'from reinteract.statement import Statement; Statement.get_current() != None',
        repr(True))

    #--------------------------------------------------------------------------------------
    pass