Esempio n. 1
0
class test_interface(TestCase):
    def setUp(self):
        self.interface = Interface('/foo[0:3]')
        self.interface['/foo[0]', 'interface', 'io'] = [0, 'in']
        self.interface['/foo[1:3]', 'interface', 'io'] = [0, 'out']

    def test_clear(self):
        i = Interface('/foo[0:4]')
        i.clear()
        assert len(i) == 0

    def test_create_empty(self):
        i = Interface('')
        assert len(i) == 0

    def test_assign_unequal_levels(self):
        i = Interface('/a/b/c,/x/y')

        # This should succeed without exception:
        i['/x/y', 'interface'] = 0

    def test_create_dup_identifiers(self):
        self.assertRaises(Exception, Interface, '/foo[0],/foo[0]')

    def test_equals(self):
        i = Interface('/foo[0:2],/bar[0:2]')
        i['/foo[0]'] = [0, 'in', 'gpot']
        i['/bar[0]'] = [0, 'out', 'gpot']
        i['/foo[1]'] = [1, 'in', 'spike']
        i['/bar[1]'] = [1, 'out', 'spike']
        j = Interface('/foo[0:2],/bar[0:2]')
        j['/foo[0]'] = [0, 'in', 'gpot']
        j['/bar[0]'] = [0, 'out', 'gpot']
        j['/foo[1]'] = [1, 'in', 'spike']
        j['/bar[1]'] = [1, 'out', 'spike']
        assert i.equals(j)
        assert j.equals(i)
        j['/foo[0]'] = [0, 'in', 'spike']
        assert not i.equals(j)
        assert not j.equals(i)

    def test_get_common_ports(self):
        # Without type, single level:
        i = Interface('/foo,/bar,/baz')
        i['/*', 'interface'] = 0
        j = Interface('/bar,/baz,/qux')
        j['/*', 'interface'] = 0
        assert i.get_common_ports(0, j, 0, 'spike') == []
        self.assertItemsEqual(i.get_common_ports(0, j, 0), [('bar', ),
                                                            ('baz', )])

        # Without type, multiple levels:
        i = Interface('/foo[0:6]')
        i['/*', 'interface'] = 0
        j = Interface('/foo[3:9]')
        j['/*', 'interface'] = 0
        assert i.get_common_ports(0, j, 0, 'spike') == []
        self.assertItemsEqual(i.get_common_ports(0, j, 0), [('foo', 3),
                                                            ('foo', 4),
                                                            ('foo', 5)])

        # With type, single level:
        i = Interface('/foo,/bar,/baz')
        i['/foo,/bar', 'interface', 'type'] = [0, 'spike']
        j = Interface('/bar,/baz,/qux')
        j['/bar,/baz', 'interface', 'type'] = [0, 'spike']
        self.assertItemsEqual(i.get_common_ports(0, j, 0, 'spike'),
                              [('bar', )])

        # With type, multiple levels:
        i = Interface('/foo[0:6]')
        i['/foo[3,4]', 'interface', 'type'] = [0, 'spike']
        j = Interface('/foo[3:9]')
        j['/foo[3,4]', 'interface', 'type'] = [0, 'spike']
        self.assertItemsEqual(i.get_common_ports(0, j, 0, 'spike'),
                              [('foo', 3), ('foo', 4)])

    def test_get_common_ports_unequal_num_levels(self):
        # Without type, some with only one level:
        i = Interface('/foo[0:6],/bar')
        i['/*', 'interface'] = 0
        j = Interface('/bar,/baz')
        j['/*', 'interface'] = 0
        assert i.get_common_ports(0, j, 0, 'spike') == []
        self.assertItemsEqual(i.get_common_ports(0, j, 0), [('bar', )])

        # Without type, more than one level:
        i = Interface('/foo[0:6],/bar[0:2]/baz')
        i['/*', 'interface'] = 0
        j = Interface('/foo[3:9]')
        j['/*', 'interface'] = 0
        assert i.get_common_ports(0, j, 0, 'spike') == []
        self.assertItemsEqual(i.get_common_ports(0, j, 0), [('foo', 3),
                                                            ('foo', 4),
                                                            ('foo', 5)])

        # With type, some with only one level:
        i = Interface('/foo[0:6],/bar,/baz')
        i['/foo[3,4],/bar', 'interface', 'type'] = [0, 'spike']
        j = Interface('/bar,/baz,/qux')
        j['/bar,/baz', 'interface', 'type'] = [0, 'spike']
        self.assertItemsEqual(i.get_common_ports(0, j, 0, 'spike'),
                              [('bar', )])

        # With type, more than one level:
        i = Interface('/foo[0:6],/bar[0:2]/baz')
        i['/foo[3,4]', 'interface', 'type'] = [0, 'spike']
        j = Interface('/foo[3:9]')
        j['/foo[3,4]', 'interface', 'type'] = [0, 'spike']
        self.assertItemsEqual(i.get_common_ports(0, j, 0, 'spike'),
                              [('foo', 3), ('foo', 4)])

    def test_to_selectors(self):
        # Selector with multiple levels:
        i = Interface('/foo[0:4]')
        i['/foo[0:2]', 'interface'] = 0
        i['/foo[2:4]', 'interface'] = 1
        self.assertSequenceEqual(i.to_selectors(0), ['/foo[0]', '/foo[1]'])
        self.assertSequenceEqual(i.to_selectors(),
                                 ['/foo[0]', '/foo[1]', '/foo[2]', '/foo[3]'])

        # Selector with single level:
        i = Interface('/[foo,bar,baz]')
        i['/foo', 'interface'] = 0
        i['/bar', 'interface'] = 0
        i['/baz', 'interface'] = 1
        self.assertSequenceEqual(i.to_selectors(0), ['/foo', '/bar'])
        self.assertSequenceEqual(i.to_selectors(), ['/foo', '/bar', '/baz'])

    def test_to_tuples_multi_levels(self):
        i = Interface('/foo[0:4]')
        i['/foo[0:2]', 'interface'] = 0
        i['/foo[2:4]', 'interface'] = 1
        self.assertSequenceEqual(i.to_tuples(0), [('foo', 0), ('foo', 1)])
        self.assertSequenceEqual(i.to_tuples(), [('foo', 0), ('foo', 1),
                                                 ('foo', 2), ('foo', 3)])

    def test_to_tuples_single_level(self):
        i = Interface('[0:4]')
        i['[0:2]', 'interface'] = 0
        i['[2:4]', 'interface'] = 1
        self.assertSequenceEqual(i.to_tuples(0), [(0, ), (1, )])
        self.assertSequenceEqual(i.to_tuples(), [(0, ), (1, ), (2, ), (3, )])

    def test_data_select(self):
        # Selector with multiple levels:
        i = Interface('/foo[0:3]')
        i['/foo[0]', 'interface', 'io'] = [0, 'in']
        i['/foo[1:3]', 'interface', 'io'] = [0, 'out']
        j = i.data_select(lambda x: x['io'] != 'in')
        assert_index_equal(j.data.index,
                           pd.MultiIndex.from_tuples([('foo', 1), ('foo', 2)]))

        # Selector with single level:
        i = Interface('/[foo,bar,baz]')
        i['/[foo,bar]', 'interface', 'io'] = [0, 'in']
        i['/baz', 'interface', 'io'] = [0, 'out']
        j = i.data_select(lambda x: x['io'] != 'in')
        assert_index_equal(j.data.index, pd.Index(['baz']))

        # Selectors with different numbers of levels:
        i = Interface('/a/b/c,/x/y')
        i['/a/b/c', 'interface', 'io'] = [0, 'in']
        j = i.data_select(lambda x: x['io'] != 'in')
        assert_index_equal(j.data.index,
                           pd.MultiIndex.from_tuples([('x', 'y', '')]))

    def test_from_df_index(self):
        idx = pd.Index(['foo', 'bar', 'baz'])
        data = [(0, 'in', 'spike'), (1, 'in', 'gpot'), (1, 'out', 'gpot')]
        columns = ['interface', 'io', 'type']
        df = pd.DataFrame(data, index=idx, columns=columns)
        i = Interface.from_df(df)
        assert_index_equal(i.data.index, idx)
        assert_frame_equal(i.data, df)

    def test_from_df_index_empty(self):
        idx = pd.Index([])
        data = None
        columns = ['interface', 'io', 'type']
        df = pd.DataFrame(data, index=idx, columns=columns)
        i = Interface.from_df(df)
        assert_index_equal(i.data.index, idx)
        assert_frame_equal(i.data, df)

    def test_from_df_multiindex(self):
        idx = pd.MultiIndex.from_tuples([('foo', 0), ('foo', 1), ('foo', 2)])
        data = [(0, 'in', 'spike'), (1, 'in', 'gpot'), (1, 'out', 'gpot')]
        columns = ['interface', 'io', 'type']
        df = pd.DataFrame(data, index=idx, columns=columns)
        i = Interface.from_df(df)
        assert_index_equal(i.data.index, idx)
        assert_frame_equal(i.data, df)

    def test_from_df_multiindex_empty(self):
        idx = pd.MultiIndex(levels=[['a', 'b'], [0, 1]], labels=[[], []])
        data = None
        columns = ['interface', 'io', 'type']
        df = pd.DataFrame(data, index=idx, columns=columns)
        i = Interface.from_df(df)
        assert_index_equal(i.data.index, idx)
        assert_frame_equal(i.data, df)

    def test_from_df_dup(self):
        idx = pd.MultiIndex.from_tuples([('foo', 0), ('foo', 0), ('foo', 2)])
        data = [(0, 'in', 'spike'), (1, 'in', 'gpot'), (1, 'out', 'gpot')]
        columns = ['interface', 'io', 'type']
        df = pd.DataFrame(data, index=idx, columns=columns)
        self.assertRaises(Exception, Interface.from_df, df)

    def test_from_dict(self):
        i = Interface.from_dict({'/foo[0:3]': np.nan})
        assert_index_equal(
            i.data.index,
            pd.MultiIndex.from_tuples([('foo', 0), ('foo', 1), ('foo', 2)]))

    def test_from_graph(self):
        i = Interface('/foo[0:3]')
        i['/foo[0]'] = [0, 'in', 'gpot']
        i['/foo[1]'] = [0, 'out', 'gpot']
        i['/foo[2]'] = [0, 'out', 'spike']
        g = nx.Graph()
        g.add_node('/foo[0]', interface=0, io='in', type='gpot')
        g.add_node('/foo[1]', interface=0, io='out', type='gpot')
        g.add_node('/foo[2]', interface=0, io='out', type='spike')
        ig = Interface.from_graph(g)
        assert_index_equal(i.data.index, ig.data.index)
        assert_frame_equal(i.data, ig.data)

    def test_is_in_interfaces(self):
        # Selector with multiple levels:
        i = Interface('/foo[0:3]')
        i['/foo[0]', 'interface', 'io'] = [0, 'in']
        i['/foo[1:3]', 'interface', 'io'] = [0, 'out']
        assert i.is_in_interfaces('/foo[0:3]') == True
        assert i.is_in_interfaces('/foo[0:4]') == False
        assert i.is_in_interfaces('/foo') == False

        # Selector with single level:
        i = Interface('/[foo,bar]')
        i['/foo', 'interface', 'io'] = [0, 'in']
        i['/bar', 'interface', 'io'] = [1, 'out']
        assert i.is_in_interfaces('/foo') == True
        assert i.is_in_interfaces('/qux') == False

        # Selectors comprising identifiers with different numbers of levels
        i = Interface('/foo,/bar[0:3]')
        i['/foo', 'interface', 'io'] = [0, 'in']
        i['/bar[0:3]', 'interface', 'io'] = [1, 'out']
        assert i.is_in_interfaces('/foo') == True
        assert i.is_in_interfaces('/bar[0]') == True
        assert i.is_in_interfaces('/bar') == False

    def test_in_ports(self):
        # Selector with multiple levels:
        i = Interface('/foo[0:2]')
        i['/foo[0]'] = [0, 'in', 'spike']
        i['/foo[1]'] = [1, 'out', 'spike']
        df = pd.DataFrame([(0, 'in', 'spike')],
                          pd.MultiIndex.from_tuples([('foo', 0)],
                                                    names=['0', '1']),
                          ['interface', 'io', 'type'],
                          dtype=object)

        # Test returning result as Interface:
        assert_frame_equal(i.in_ports(0).data, df)

        # Test returning result as list of tuples:
        self.assertItemsEqual(i.in_ports(0, True), df.index.tolist())

        # Selector with single level:
        i = Interface('/[foo,bar]')
        i['/foo'] = [0, 'in', 'spike']
        i['/bar'] = [1, 'out', 'spike']
        df = pd.DataFrame([(0, 'in', 'spike')],
                          pd.MultiIndex.from_tuples([('foo', )], names=['0']),
                          ['interface', 'io', 'type'],
                          dtype=object)

        # Test returning result as Interface:
        assert_frame_equal(i.in_ports(0).data, df)

        # Test returning result as list of tuples:
        self.assertItemsEqual(i.in_ports(0, True), df.index.tolist())

    def test_interface_ports(self):
        # Selector with multiple levels:
        i = Interface('/foo[0:4]')
        i['/foo[0:2]', 'interface'] = 0
        i['/foo[2:4]', 'interface'] = 1
        j = Interface('/foo[2:4]')
        j['/foo[2:4]', 'interface'] = 1

        # Test returning result as Interface:
        assert_frame_equal(i.interface_ports(1).data, j.data)

        # Test returning result as list of tuples:
        self.assertItemsEqual(i.interface_ports(1, True),
                              j.data.index.tolist())

        # Selector with single level:
        i = Interface('/[foo,bar,baz]')
        i['/[foo,bar]', 'interface'] = 0
        i['/baz', 'interface'] = 1
        j = Interface('/baz')
        j['/baz', 'interface'] = 1

        # Test returning result as Interface:
        assert_frame_equal(i.interface_ports(1).data, j.data)

        # Test returning result as list of tuples:
        self.assertItemsEqual(i.interface_ports(1, True),
                              j.data.index.tolist())

    def test_out_ports(self):
        # Selector with multiple levels:
        i = Interface('/foo[0:2]')
        i['/foo[0]'] = [0, 'in', 'spike']
        i['/foo[1]'] = [1, 'out', 'spike']
        df = pd.DataFrame([(1, 'out', 'spike')],
                          pd.MultiIndex.from_tuples([('foo', 1)],
                                                    names=['0', '1']),
                          ['interface', 'io', 'type'],
                          dtype=object)

        # Test returning result as Interface:
        assert_frame_equal(i.out_ports(1).data, df)

        # Test returning result as list of tuples:
        self.assertItemsEqual(i.out_ports(1, True), df.index.tolist())

        # Selector with single level:
        i = Interface('/[foo,bar]')
        i['/foo'] = [0, 'in', 'spike']
        i['/bar'] = [1, 'out', 'spike']
        df = pd.DataFrame([(1, 'out', 'spike')],
                          pd.MultiIndex.from_tuples([('bar', )], names=['0']),
                          ['interface', 'io', 'type'],
                          dtype=object)

        # Test returning result as Interface:
        assert_frame_equal(i.out_ports(1).data, df)

        # Test returning result as list of tuples:
        self.assertItemsEqual(i.out_ports(1, True), df.index.tolist())

    def test_gpot_ports(self):
        i = Interface('/foo[0:6]')
        i['/foo[0]'] = [0, 'in', 'spike']
        i['/foo[1:3]'] = [0, 'out', 'spike']
        i['/foo[3]'] = [0, 'in', 'gpot']
        i['/foo[4:6]'] = [0, 'out', 'gpot']
        j = Interface('/foo[3:6]')
        j['/foo[3]'] = [0, 'in', 'gpot']
        j['/foo[4:6]'] = [0, 'out', 'gpot']

        # Test returning result as Interface:
        assert_frame_equal(i.gpot_ports(0).data, j.data)

        # Test returning result as list of tuples:
        self.assertItemsEqual(i.gpot_ports(0, True), j.data.index.tolist())

    def test_spike_ports(self):
        i = Interface('/foo[0:6]')
        i['/foo[0]'] = [0, 'in', 'spike']
        i['/foo[1:3]'] = [0, 'out', 'spike']
        i['/foo[3]'] = [0, 'in', 'gpot']
        i['/foo[4:6]'] = [0, 'out', 'gpot']
        j = Interface('/foo[0:3]')
        j['/foo[0]'] = [0, 'in', 'spike']
        j['/foo[1:3]'] = [0, 'out', 'spike']

        # Return result as Interface:
        assert_frame_equal(i.spike_ports(0).data, j.data)

        # Test returning result as list of tuples:
        self.assertItemsEqual(i.spike_ports(0, True), j.data.index.tolist())

    def test_port_select(self):
        i = self.interface.port_select(lambda x: x[1] >= 1)
        assert_index_equal(i.data.index,
                           pd.MultiIndex.from_tuples([('foo', 1), ('foo', 2)]))

    def test_index(self):
        assert_index_equal(
            self.interface.index,
            pd.MultiIndex(levels=[['foo'], [0, 1, 2]],
                          labels=[[0, 0, 0], [0, 1, 2]],
                          names=['0', '1']))

    def test_interface_ids(self):
        i = Interface('/foo[0:4]')
        i['/foo[0:2]', 'interface', 'io'] = [0, 'out']
        i['/foo[2:4]', 'interface', 'io'] = [1, 'in']
        assert i.interface_ids == set([0, 1])

    def test_io_inv(self):
        i = Interface('/foo[0:4]')
        i['/foo[0:2]', 'interface', 'io'] = [0, 'out']
        i['/foo[2:4]', 'interface', 'io'] = [1, 'in']
        j = Interface('/foo[0:4]')
        j['/foo[0:2]', 'interface', 'io'] = [0, 'in']
        j['/foo[2:4]', 'interface', 'io'] = [1, 'out']
        assert_frame_equal(i.data, j.io_inv.data)

    def test_is_compatible_sel_order(self):
        """
        Interfaces with individually compatible ports that are ordered in
        different ways should still be deemed compatible.
        """

        # Selectors with multiple levels:
        i = Interface('/foo[0:2],/bar[0:2]')
        i['/foo[0:2]', 'interface', 'io'] = [0, 'in']
        i['/bar[0:2]', 'interface', 'io'] = [0, 'out']
        j = Interface('/bar[0:2],/foo[0:2]')
        j['/bar[0:2]', 'interface', 'io'] = [1, 'in']
        j['/foo[0:2]', 'interface', 'io'] = [1, 'out']
        assert i.is_compatible(0, j, 1)

        # Selectors with single level:
        i = Interface('/foo,/bar,/baz,/qux')
        i['/[foo,bar]', 'interface', 'io'] = [0, 'in']
        i['/[baz,qux]', 'interface', 'io'] = [0, 'out']
        j = Interface('/bar,/foo,/qux,/baz')
        j['/[baz,qux]', 'interface', 'io'] = [1, 'in']
        j['/[foo,bar]', 'interface', 'io'] = [1, 'out']
        assert i.is_compatible(0, j, 1)

    def test_is_compatible_both_dirs(self):
        """
        It should be possible to define compatible interfaces containing both
        input and output ports.
        """

        i = Interface('/foo[0:4]')
        i['/foo[0:2]', 'interface', 'io'] = [0, 'out']
        i['/foo[2:4]', 'interface', 'io'] = [0, 'in']
        j = Interface('/foo[0:4]')
        j['/foo[0:2]', 'interface', 'io'] = [1, 'in']
        j['/foo[2:4]', 'interface', 'io'] = [1, 'out']
        assert i.is_compatible(0, j, 1)

    def test_is_compatible_both_dirs_types(self):
        """
        It should be possible to define compatible interfaces containing both
        input and output ports with specified types.
        """

        i = Interface('/foo[0:4]')
        i['/foo[0:2]'] = [0, 'out', 'gpot']
        i['/foo[2:4]'] = [0, 'in', 'spike']
        j = Interface('/foo[0:4]')
        j['/foo[0:2]'] = [1, 'in', 'gpot']
        j['/foo[2:4]'] = [1, 'out', 'spike']
        assert i.is_compatible(0, j, 1)

    def test_is_compatible_one_dir(self):
        i = Interface('/foo[0:2]')
        i['/foo[0:2]', 'interface', 'io'] = [0, 'out']
        j = Interface('/foo[0:2]')
        j['/foo[0:2]', 'interface', 'io'] = [1, 'in']
        assert i.is_compatible(0, j, 1)

    def test_is_compatible_one_dir_types(self):
        i = Interface('/foo[0:2]')
        i['/foo[0:2]'] = [0, 'out', 'spike']
        j = Interface('/foo[0:2]')
        j['/foo[0:2]'] = [1, 'in', 'spike']
        assert i.is_compatible(0, j, 1)

    def test_is_compatible_with_nulls(self):
        """
        Interfaces can be compatible even if some of their ports do not have a
        set input or output status.
        """

        i = Interface('/foo[0:3]')
        i['/foo[0:2]', 'interface', 'io'] = [0, 'out']
        i['/foo[2]', 'interface'] = 0
        j = Interface('/foo[0:3]')
        j['/foo[0:2]', 'interface', 'io'] = [1, 'in']
        j['/foo[2]', 'interface'] = 1
        assert i.is_compatible(0, j, 1)

    def test_is_compatible_with_nulls_types(self):
        """
        Interfaces can be compatible even if some of their ports do not have a
        set type.
        """

        i = Interface('/foo[0:3]')
        i['/foo[0:2]'] = [0, 'out', 'gpot']
        i['/foo[2]', 'interface'] = 0
        j = Interface('/foo[0:3]')
        j['/foo[0:2]'] = [1, 'in', 'gpot']
        j['/foo[2]', 'interface'] = 1
        assert i.is_compatible(0, j, 1)

    def test_is_compatible_subsets(self):
        """
        Interfaces that both share a subset of compatible ports can be deemed
        compatible by setting the `allow_subsets` option of the compatibility
        test.
        """

        i = Interface('/foo[0:6]')
        i['/foo[0:3]'] = [0, 'out', 'gpot']
        i['/foo[3:6]'] = [0, 'out', 'spike']
        j = Interface('/foo[0:6]')
        j['/foo[0:2]'] = [1, 'in', 'gpot']
        j['/foo[3:5]'] = [1, 'in', 'spike']
        k = Interface('/foo[0:6]')
        assert i.is_compatible(0, j, 1, True)
        assert i.is_compatible(0, k, 1, True) == False

    def test_is_compatible_subsets_with_null_types(self):
        """
        Interfaces that both share a subset of compatible ports can be deemed
        compatible by setting the `allow_subsets` option of the compatibility
        test even when the types are null.
        """

        i = Interface('/foo[0:6]')
        i['/foo[0:3]'] = [0, 'out']
        i['/foo[3:6]'] = [0, 'out']
        j = Interface('/foo[0:6]')
        j['/foo[0:2]'] = [1, 'in']
        j['/foo[3:5]'] = [1, 'in']
        k = Interface('/foo[0:6]')
        assert i.is_compatible(0, j, 1, True)
        assert i.is_compatible(0, k, 1, True) == False

    def test_which_int_unset(self):
        i = Interface('/foo[0:4]')
        assert i.which_int('/foo[0:2]') == set()

    def test_which_int_set(self):
        i = Interface('/foo[0:4]')
        i['/foo[0]', 'interface', 'io'] = [0, 'out']
        i['/foo[1]', 'interface', 'io'] = [0, 'in']
        i['/foo[2]', 'interface', 'io'] = [1, 'in']
        i['/foo[3]', 'interface', 'io'] = [1, 'out']
        assert i.which_int('/foo[0:2]') == {0}
        assert i.which_int('/foo[0:4]') == {0, 1}
Esempio n. 2
0
class test_interface(TestCase):
    def setUp(self):
        self.interface = Interface('/foo[0:3]')
        self.interface['/foo[0]', 'interface', 'io'] = [0, 'in']
        self.interface['/foo[1:3]', 'interface', 'io'] = [0, 'out']

    def test_clear(self):
        i = Interface('/foo[0:4]')
        i.clear()
        assert len(i) == 0

    def test_create_empty(self):
        i = Interface('')
        assert len(i) == 0

    def test_assign_unequal_levels(self):
        i = Interface('/a/b/c,/x/y')

        # This should succeed without exception:
        i['/x/y', 'interface'] = 0
        
    def test_create_dup_identifiers(self):
        self.assertRaises(Exception, Interface, '/foo[0],/foo[0]')

    def test_equals(self):
        i = Interface('/foo[0:2],/bar[0:2]')
        i['/foo[0]'] = [0, 'in', 'gpot']
        i['/bar[0]'] = [0, 'out', 'gpot']
        i['/foo[1]'] = [1, 'in', 'spike']
        i['/bar[1]'] = [1, 'out', 'spike']
        j = Interface('/foo[0:2],/bar[0:2]')
        j['/foo[0]'] = [0, 'in', 'gpot']
        j['/bar[0]'] = [0, 'out', 'gpot']
        j['/foo[1]'] = [1, 'in', 'spike']
        j['/bar[1]'] = [1, 'out', 'spike']
        assert i.equals(j)
        assert j.equals(i)
        j['/foo[0]'] = [0, 'in', 'spike']
        assert not i.equals(j)
        assert not j.equals(i)

    def test_get_common_ports(self):
        # Without type, single level:
        i = Interface('/foo,/bar,/baz')
        i['/*', 'interface'] = 0
        j = Interface('/bar,/baz,/qux')
        j['/*', 'interface'] = 0
        assert i.get_common_ports(0, j, 0, 'spike') == []
        self.assertItemsEqual(i.get_common_ports(0, j, 0),
                              [('bar',), ('baz',)])

        # Without type, multiple levels:
        i = Interface('/foo[0:6]')
        i['/*', 'interface'] = 0
        j = Interface('/foo[3:9]')
        j['/*', 'interface'] = 0
        assert i.get_common_ports(0, j, 0, 'spike') == []
        self.assertItemsEqual(i.get_common_ports(0, j, 0),
                              [('foo', 3), ('foo', 4), ('foo', 5)])

        # With type, single level:
        i = Interface('/foo,/bar,/baz')
        i['/foo,/bar', 'interface', 'type'] = [0, 'spike']
        j = Interface('/bar,/baz,/qux')
        j['/bar,/baz', 'interface', 'type'] = [0, 'spike']
        self.assertItemsEqual(i.get_common_ports(0, j, 0, 'spike'),
                              [('bar',)])
        
        # With type, multiple levels:
        i = Interface('/foo[0:6]')
        i['/foo[3,4]', 'interface', 'type'] = [0, 'spike']
        j = Interface('/foo[3:9]')
        j['/foo[3,4]', 'interface', 'type'] = [0, 'spike']
        self.assertItemsEqual(i.get_common_ports(0, j, 0, 'spike'),
                              [('foo', 3), ('foo', 4)])


    def test_get_common_ports_unequal_num_levels(self):
        # Without type, some with only one level:
        i = Interface('/foo[0:6],/bar')
        i['/*', 'interface'] = 0
        j = Interface('/bar,/baz')
        j['/*', 'interface'] = 0
        assert i.get_common_ports(0, j, 0, 'spike') == []
        self.assertItemsEqual(i.get_common_ports(0, j, 0),
                              [('bar',)])

        # Without type, more than one level:
        i = Interface('/foo[0:6],/bar[0:2]/baz')
        i['/*', 'interface'] = 0
        j = Interface('/foo[3:9]')
        j['/*', 'interface'] = 0
        assert i.get_common_ports(0, j, 0, 'spike') == []
        self.assertItemsEqual(i.get_common_ports(0, j, 0),
                              [('foo', 3), ('foo', 4), ('foo', 5)])

        # With type, some with only one level:
        i = Interface('/foo[0:6],/bar,/baz')
        i['/foo[3,4],/bar', 'interface', 'type'] = [0, 'spike']
        j = Interface('/bar,/baz,/qux')
        j['/bar,/baz', 'interface', 'type'] = [0, 'spike']
        self.assertItemsEqual(i.get_common_ports(0, j, 0, 'spike'),
                              [('bar',)])

        # With type, more than one level:
        i = Interface('/foo[0:6],/bar[0:2]/baz')
        i['/foo[3,4]', 'interface', 'type'] = [0, 'spike']
        j = Interface('/foo[3:9]')
        j['/foo[3,4]', 'interface', 'type'] = [0, 'spike']
        self.assertItemsEqual(i.get_common_ports(0, j, 0, 'spike'),
                              [('foo', 3), ('foo', 4)])

    def test_to_selectors(self):
        # Selector with multiple levels:
        i = Interface('/foo[0:4]')
        i['/foo[0:2]', 'interface'] = 0
        i['/foo[2:4]', 'interface'] = 1
        self.assertSequenceEqual(i.to_selectors(0),
                                 ['/foo[0]',
                                  '/foo[1]'])
        self.assertSequenceEqual(i.to_selectors(),
                                 ['/foo[0]',
                                  '/foo[1]',
                                  '/foo[2]',
                                  '/foo[3]'])

        # Selector with single level:
        i = Interface('/[foo,bar,baz]')
        i['/foo', 'interface'] = 0
        i['/bar', 'interface'] = 0
        i['/baz', 'interface'] = 1
        self.assertSequenceEqual(i.to_selectors(0),
                                 ['/foo', 
                                  '/bar'])
        self.assertSequenceEqual(i.to_selectors(), 
                                 ['/foo', 
                                  '/bar',
                                  '/baz'])

    def test_to_tuples_multi_levels(self):
        i = Interface('/foo[0:4]')
        i['/foo[0:2]', 'interface'] = 0
        i['/foo[2:4]', 'interface'] = 1
        self.assertSequenceEqual(i.to_tuples(0),
                                 [('foo', 0), 
                                  ('foo', 1)])
        self.assertSequenceEqual(i.to_tuples(), 
                                 [('foo', 0), 
                                  ('foo', 1),
                                  ('foo', 2),
                                  ('foo', 3)])

    def test_to_tuples_single_level(self):
        i = Interface('[0:4]')
        i['[0:2]', 'interface'] = 0
        i['[2:4]', 'interface'] = 1
        self.assertSequenceEqual(i.to_tuples(0),
                                 [(0,), (1,)])
        self.assertSequenceEqual(i.to_tuples(),
                                 [(0,), (1,), (2,), (3,)])

    def test_data_select(self):
        # Selector with multiple levels:
        i = Interface('/foo[0:3]')
        i['/foo[0]', 'interface', 'io'] = [0, 'in']
        i['/foo[1:3]', 'interface', 'io'] = [0, 'out']
        j = i.data_select(lambda x: x['io'] != 'in')
        assert_index_equal(j.data.index,
                           pd.MultiIndex.from_tuples([('foo', 1),
                                                      ('foo', 2)]))

        # Selector with single level:
        i = Interface('/[foo,bar,baz]')
        i['/[foo,bar]', 'interface', 'io'] = [0, 'in']
        i['/baz', 'interface', 'io'] = [0, 'out']
        j = i.data_select(lambda x: x['io'] != 'in')
        assert_index_equal(j.data.index,
                           pd.Index(['baz']))

        # Selectors with different numbers of levels:
        i = Interface('/a/b/c,/x/y')
        i['/a/b/c', 'interface', 'io'] = [0, 'in']
        j = i.data_select(lambda x: x['io'] != 'in')
        assert_index_equal(j.data.index,
                           pd.MultiIndex.from_tuples([('x', 'y', '')]))

    def test_from_df_index(self):
        idx = pd.Index(['foo', 'bar', 'baz'])
        data = [(0, 'in', 'spike'),
                (1, 'in', 'gpot'),
                (1, 'out', 'gpot')]
        columns = ['interface', 'io', 'type']
        df = pd.DataFrame(data, index=idx, columns=columns)
        i = Interface.from_df(df)
        assert_index_equal(i.data.index, idx)
        assert_frame_equal(i.data, df)

    def test_from_df_index_empty(self):
        idx = pd.Index([])
        data = None
        columns = ['interface', 'io', 'type']
        df = pd.DataFrame(data, index=idx, columns=columns)
        i = Interface.from_df(df)
        assert_index_equal(i.data.index, idx)
        assert_frame_equal(i.data, df)

    def test_from_df_multiindex(self):
        idx = pd.MultiIndex.from_tuples([('foo', 0),
                                         ('foo', 1),
                                         ('foo', 2)])
        data = [(0, 'in', 'spike'),
                (1, 'in', 'gpot'),
                (1, 'out', 'gpot')]
        columns = ['interface', 'io', 'type']
        df = pd.DataFrame(data, index=idx, columns=columns)
        i = Interface.from_df(df)
        assert_index_equal(i.data.index, idx)
        assert_frame_equal(i.data, df)

    def test_from_df_multiindex_empty(self):
        idx = pd.MultiIndex(levels=[['a', 'b'], [0, 1]],
                            labels=[[],[]])
        data = None
        columns = ['interface', 'io', 'type']
        df = pd.DataFrame(data, index=idx, columns=columns)
        i = Interface.from_df(df)
        assert_index_equal(i.data.index, idx)
        assert_frame_equal(i.data, df)

    def test_from_df_dup(self):
        idx = pd.MultiIndex.from_tuples([('foo', 0),
                                         ('foo', 0),
                                         ('foo', 2)])
        data  = [(0, 'in', 'spike'),
                 (1, 'in', 'gpot'),
                 (1, 'out', 'gpot')]
        columns = ['interface', 'io', 'type']
        df = pd.DataFrame(data, index=idx, columns=columns)
        self.assertRaises(Exception, Interface.from_df, df)

    def test_from_dict(self):
        i = Interface.from_dict({'/foo[0:3]': np.nan})
        assert_index_equal(i.data.index,
                           pd.MultiIndex.from_tuples([('foo', 0),
                                                      ('foo', 1),
                                                      ('foo', 2)]))

    def test_from_graph(self):
        i = Interface('/foo[0:3]')
        i['/foo[0]'] = [0, 'in', 'gpot']
        i['/foo[1]'] = [0, 'out', 'gpot']
        i['/foo[2]'] = [0, 'out', 'spike']
        g = nx.Graph()
        g.add_node('/foo[0]', interface=0, io='in', type='gpot')
        g.add_node('/foo[1]', interface=0, io='out', type='gpot')
        g.add_node('/foo[2]', interface=0, io='out', type='spike')
        ig = Interface.from_graph(g)
        assert_index_equal(i.data.index, ig.data.index)
        assert_frame_equal(i.data, ig.data)
    
    def test_is_in_interfaces(self):
        # Selector with multiple levels:
        i = Interface('/foo[0:3]')
        i['/foo[0]', 'interface', 'io'] = [0, 'in']
        i['/foo[1:3]', 'interface', 'io'] = [0, 'out']
        assert i.is_in_interfaces('/foo[0:3]') == True
        assert i.is_in_interfaces('/foo[0:4]') == False
        assert i.is_in_interfaces('/foo') == False

        # Selector with single level:
        i = Interface('/[foo,bar]')
        i['/foo', 'interface', 'io'] = [0, 'in']
        i['/bar', 'interface', 'io'] = [1, 'out']
        assert i.is_in_interfaces('/foo') == True
        assert i.is_in_interfaces('/qux') == False

        # Selectors comprising identifiers with different numbers of levels
        i = Interface('/foo,/bar[0:3]')
        i['/foo', 'interface', 'io'] = [0, 'in']
        i['/bar[0:3]', 'interface', 'io'] = [1, 'out']
        assert i.is_in_interfaces('/foo') == True
        assert i.is_in_interfaces('/bar[0]') == True
        assert i.is_in_interfaces('/bar') == False
        
    def test_in_ports(self):
        # Selector with multiple levels:
        i = Interface('/foo[0:2]')
        i['/foo[0]'] = [0, 'in', 'spike']
        i['/foo[1]'] = [1, 'out', 'spike']
        df = pd.DataFrame([(0, 'in', 'spike')],
                          pd.MultiIndex.from_tuples([('foo', 0)],
                                                    names=['0', '1']),
                          ['interface', 'io', 'type'],
                          dtype=object)

        # Test returning result as Interface:
        assert_frame_equal(i.in_ports(0).data, df)

        # Test returning result as list of tuples:
        self.assertItemsEqual(i.in_ports(0, True), df.index.tolist())

        # Selector with single level:
        i = Interface('/[foo,bar]')
        i['/foo'] = [0, 'in', 'spike']
        i['/bar'] = [1, 'out', 'spike']
        df = pd.DataFrame([(0, 'in', 'spike')],
                          pd.MultiIndex.from_tuples([('foo',)],
                                                    names=['0']),
                          ['interface', 'io', 'type'],
                          dtype=object)

        # Test returning result as Interface:
        assert_frame_equal(i.in_ports(0).data, df)

        # Test returning result as list of tuples:
        self.assertItemsEqual(i.in_ports(0, True), df.index.tolist())

    def test_interface_ports(self):
        # Selector with multiple levels:
        i = Interface('/foo[0:4]')
        i['/foo[0:2]', 'interface'] = 0
        i['/foo[2:4]', 'interface'] = 1
        j = Interface('/foo[2:4]')
        j['/foo[2:4]', 'interface'] = 1

        # Test returning result as Interface:
        assert_frame_equal(i.interface_ports(1).data, j.data)

        # Test returning result as list of tuples:
        self.assertItemsEqual(i.interface_ports(1, True), j.data.index.tolist())

        # Selector with single level:
        i = Interface('/[foo,bar,baz]')
        i['/[foo,bar]', 'interface'] = 0
        i['/baz', 'interface'] = 1
        j = Interface('/baz')
        j['/baz', 'interface'] = 1

        # Test returning result as Interface:
        assert_frame_equal(i.interface_ports(1).data, j.data)

        # Test returning result as list of tuples:
        self.assertItemsEqual(i.interface_ports(1, True), j.data.index.tolist())

    def test_out_ports(self):
        # Selector with multiple levels:
        i = Interface('/foo[0:2]')
        i['/foo[0]'] = [0, 'in', 'spike']
        i['/foo[1]'] = [1, 'out', 'spike']
        df = pd.DataFrame([(1, 'out', 'spike')],
                          pd.MultiIndex.from_tuples([('foo', 1)],
                                                    names=['0', '1']),
                          ['interface', 'io', 'type'],
                          dtype=object)

        # Test returning result as Interface:
        assert_frame_equal(i.out_ports(1).data, df)

        # Test returning result as list of tuples:
        self.assertItemsEqual(i.out_ports(1, True), df.index.tolist())

        # Selector with single level:
        i = Interface('/[foo,bar]')
        i['/foo'] = [0, 'in', 'spike']
        i['/bar'] = [1, 'out', 'spike']
        df = pd.DataFrame([(1, 'out', 'spike')],
                          pd.MultiIndex.from_tuples([('bar',)],
                                                    names=['0']),
                          ['interface', 'io', 'type'],
                          dtype=object)

        # Test returning result as Interface:
        assert_frame_equal(i.out_ports(1).data, df)

        # Test returning result as list of tuples:
        self.assertItemsEqual(i.out_ports(1, True), df.index.tolist())

    def test_gpot_ports(self):
        i = Interface('/foo[0:6]')
        i['/foo[0]'] = [0, 'in', 'spike']
        i['/foo[1:3]'] = [0, 'out', 'spike']
        i['/foo[3]'] = [0, 'in', 'gpot']
        i['/foo[4:6]'] = [0, 'out', 'gpot']
        j = Interface('/foo[3:6]')
        j['/foo[3]'] = [0, 'in', 'gpot']
        j['/foo[4:6]'] = [0, 'out', 'gpot']

        # Test returning result as Interface:
        assert_frame_equal(i.gpot_ports(0).data, j.data)

        # Test returning result as list of tuples:
        self.assertItemsEqual(i.gpot_ports(0, True),
                              j.data.index.tolist())

    def test_spike_ports(self):
        i = Interface('/foo[0:6]')
        i['/foo[0]'] = [0, 'in', 'spike']
        i['/foo[1:3]'] = [0, 'out', 'spike']
        i['/foo[3]'] = [0, 'in', 'gpot']
        i['/foo[4:6]'] = [0, 'out', 'gpot']
        j = Interface('/foo[0:3]')
        j['/foo[0]'] = [0, 'in', 'spike']
        j['/foo[1:3]'] = [0, 'out', 'spike']

        # Return result as Interface:
        assert_frame_equal(i.spike_ports(0).data, j.data)

        # Test returning result as list of tuples:
        self.assertItemsEqual(i.spike_ports(0, True),
                              j.data.index.tolist())
        
    def test_port_select(self):
        i = self.interface.port_select(lambda x: x[1] >= 1)
        assert_index_equal(i.data.index,
                           pd.MultiIndex.from_tuples([('foo', 1),
                                                      ('foo', 2)]))

    def test_index(self):
        assert_index_equal(self.interface.index,
                           pd.MultiIndex(levels=[['foo'], [0, 1, 2]],
                                         labels=[[0, 0, 0], [0, 1, 2]],
                                         names=['0', '1']))

    def test_interface_ids(self):
        i = Interface('/foo[0:4]')
        i['/foo[0:2]', 'interface', 'io'] = [0, 'out']
        i['/foo[2:4]', 'interface', 'io'] = [1, 'in']
        assert i.interface_ids == set([0, 1])

    def test_io_inv(self):
        i = Interface('/foo[0:4]')
        i['/foo[0:2]', 'interface', 'io'] = [0, 'out']
        i['/foo[2:4]', 'interface', 'io'] = [1, 'in']
        j = Interface('/foo[0:4]')
        j['/foo[0:2]', 'interface', 'io'] = [0, 'in']
        j['/foo[2:4]', 'interface', 'io'] = [1, 'out']
        assert_frame_equal(i.data, j.io_inv.data)

    def test_is_compatible_sel_order(self):
        """
        Interfaces with individually compatible ports that are ordered in
        different ways should still be deemed compatible.
        """

        # Selectors with multiple levels:
        i = Interface('/foo[0:2],/bar[0:2]')
        i['/foo[0:2]', 'interface', 'io'] = [0, 'in']
        i['/bar[0:2]', 'interface', 'io'] = [0, 'out']
        j = Interface('/bar[0:2],/foo[0:2]')
        j['/bar[0:2]', 'interface', 'io'] = [1, 'in']
        j['/foo[0:2]', 'interface', 'io'] = [1, 'out']
        assert i.is_compatible(0, j, 1)

        # Selectors with single level:
        i = Interface('/foo,/bar,/baz,/qux')
        i['/[foo,bar]', 'interface', 'io'] = [0, 'in']
        i['/[baz,qux]', 'interface', 'io'] = [0, 'out']
        j = Interface('/bar,/foo,/qux,/baz')
        j['/[baz,qux]', 'interface', 'io'] = [1, 'in']
        j['/[foo,bar]', 'interface', 'io'] = [1, 'out']
        assert i.is_compatible(0, j, 1)

    def test_is_compatible_both_dirs(self):
        """
        It should be possible to define compatible interfaces containing both
        input and output ports.
        """

        i = Interface('/foo[0:4]')
        i['/foo[0:2]', 'interface', 'io'] = [0, 'out']
        i['/foo[2:4]', 'interface', 'io'] = [0, 'in']
        j = Interface('/foo[0:4]')
        j['/foo[0:2]', 'interface', 'io'] = [1, 'in']
        j['/foo[2:4]', 'interface', 'io'] = [1, 'out']
        assert i.is_compatible(0, j, 1)

    def test_is_compatible_both_dirs_types(self):
        """
        It should be possible to define compatible interfaces containing both
        input and output ports with specified types.
        """

        i = Interface('/foo[0:4]')
        i['/foo[0:2]'] = [0, 'out', 'gpot']
        i['/foo[2:4]'] = [0, 'in', 'spike']
        j = Interface('/foo[0:4]')
        j['/foo[0:2]'] = [1, 'in', 'gpot']
        j['/foo[2:4]'] = [1, 'out', 'spike']
        assert i.is_compatible(0, j, 1)

    def test_is_compatible_one_dir(self):
        i = Interface('/foo[0:2]')
        i['/foo[0:2]', 'interface', 'io'] = [0, 'out']
        j = Interface('/foo[0:2]')
        j['/foo[0:2]', 'interface', 'io'] = [1, 'in']
        assert i.is_compatible(0, j, 1)

    def test_is_compatible_one_dir_types(self):
        i = Interface('/foo[0:2]')
        i['/foo[0:2]'] = [0, 'out', 'spike']
        j = Interface('/foo[0:2]')
        j['/foo[0:2]'] = [1, 'in', 'spike']
        assert i.is_compatible(0, j, 1)

    def test_is_compatible_with_nulls(self):
        """
        Interfaces can be compatible even if some of their ports do not have a
        set input or output status.
        """

        i = Interface('/foo[0:3]')
        i['/foo[0:2]', 'interface', 'io'] = [0, 'out']
        i['/foo[2]', 'interface'] = 0
        j = Interface('/foo[0:3]')
        j['/foo[0:2]', 'interface', 'io'] = [1, 'in']
        j['/foo[2]', 'interface'] = 1
        assert i.is_compatible(0, j, 1)

    def test_is_compatible_with_nulls_types(self):
        """
        Interfaces can be compatible even if some of their ports do not have a
        set type.
        """

        i = Interface('/foo[0:3]')
        i['/foo[0:2]'] = [0, 'out', 'gpot']
        i['/foo[2]', 'interface'] = 0
        j = Interface('/foo[0:3]')
        j['/foo[0:2]'] = [1, 'in', 'gpot']
        j['/foo[2]', 'interface'] = 1
        assert i.is_compatible(0, j, 1)

    def test_is_compatible_subsets(self):
        """
        Interfaces that both share a subset of compatible ports can be deemed
        compatible by setting the `allow_subsets` option of the compatibility
        test.
        """

        i = Interface('/foo[0:6]')
        i['/foo[0:3]'] = [0, 'out', 'gpot']
        i['/foo[3:6]'] = [0, 'out', 'spike']
        j = Interface('/foo[0:6]')
        j['/foo[0:2]'] = [1, 'in', 'gpot']
        j['/foo[3:5]'] = [1, 'in', 'spike']
        k = Interface('/foo[0:6]')
        assert i.is_compatible(0, j, 1, True)
        assert i.is_compatible(0, k, 1, True) == False

    def test_is_compatible_subsets_with_null_types(self):
        """
        Interfaces that both share a subset of compatible ports can be deemed
        compatible by setting the `allow_subsets` option of the compatibility
        test even when the types are null.
        """

        i = Interface('/foo[0:6]')
        i['/foo[0:3]'] = [0, 'out']
        i['/foo[3:6]'] = [0, 'out']
        j = Interface('/foo[0:6]')
        j['/foo[0:2]'] = [1, 'in']
        j['/foo[3:5]'] = [1, 'in']
        k = Interface('/foo[0:6]')
        assert i.is_compatible(0, j, 1, True)
        assert i.is_compatible(0, k, 1, True) == False

    def test_which_int_unset(self):
        i = Interface('/foo[0:4]')
        assert i.which_int('/foo[0:2]') == set()

    def test_which_int_set(self):
        i = Interface('/foo[0:4]')
        i['/foo[0]', 'interface', 'io'] = [0, 'out']
        i['/foo[1]', 'interface', 'io'] = [0, 'in']
        i['/foo[2]', 'interface', 'io'] = [1, 'in']
        i['/foo[3]', 'interface', 'io'] = [1, 'out']
        assert i.which_int('/foo[0:2]') == {0}
        assert i.which_int('/foo[0:4]') == {0, 1}
Esempio n. 3
0
class test_interface(TestCase):
    def setUp(self):
        self.interface = Interface('/foo[0:3]')
        self.interface['/foo[0]', 'interface', 'io'] = [0, 'in']
        self.interface['/foo[1:3]', 'interface', 'io'] = [0, 'out']

    def test_clear(self):
        i = Interface('/foo[0:4]')
        i.clear()
        assert len(i) == 0

    def test_create_empty(self):
        i = Interface('')
        assert len(i) == 0

    def test_create_dup_identifiers(self):
        self.assertRaises(Exception, Interface, '/foo[0],/foo[0]')

    def test_to_selectors(self):
        i = Interface('/foo[0:4]')
        i['/foo[0:2]', 'interface'] = 0
        i['/foo[2:4]', 'interface'] = 1
        self.assertSequenceEqual(i.to_selectors(0),
                                 ['/foo[0]', 
                                  '/foo[1]'])
        self.assertSequenceEqual(i.to_selectors(), 
                                 ['/foo[0]', 
                                  '/foo[1]',
                                  '/foo[2]',
                                  '/foo[3]'])

    def test_to_tuples(self):
        i = Interface('/foo[0:4]')
        i['/foo[0:2]', 'interface'] = 0
        i['/foo[2:4]', 'interface'] = 1
        self.assertSequenceEqual(i.to_tuples(0),
                                 [('foo', 0), 
                                  ('foo', 1)])
        self.assertSequenceEqual(i.to_tuples(), 
                                 [('foo', 0), 
                                  ('foo', 1),
                                  ('foo', 2),
                                  ('foo', 3)])

        i = Interface('[0:4]')
        i['[0:2]', 'interface'] = 0
        i['[2:4]', 'interface'] = 1
        self.assertSequenceEqual(i.to_tuples(0),
                                 [(0,), (1,)])
        self.assertSequenceEqual(i.to_tuples(),
                                 [(0,), (1,), (2,), (3,)])

    def test_data_select(self):
        i = self.interface.data_select(lambda x: x['io'] >= 'out')
        assert_index_equal(i.data.index,
                           pd.MultiIndex.from_tuples([('foo', 1),
                                                      ('foo', 2)]))

    def test_from_df_index(self):
        idx = pd.Index(['foo', 'bar', 'baz'])
        data = [(0, 'in', 'spike'),
                (1, 'in', 'gpot'),
                (1, 'out', 'gpot')]
        columns = ['interface', 'io', 'type']
        df = pd.DataFrame(data, index=idx, columns=columns)
        i = Interface.from_df(df)
        assert_index_equal(i.data.index, idx)
        assert_frame_equal(i.data, df)

    def test_from_df_multiindex(self):
        idx = pd.MultiIndex.from_tuples([('foo', 0),
                                         ('foo', 1),
                                         ('foo', 2)])
        data = [(0, 'in', 'spike'),
                (1, 'in', 'gpot'),
                (1, 'out', 'gpot')]
        columns = ['interface', 'io', 'type']
        df = pd.DataFrame(data, index=idx, columns=columns)
        i = Interface.from_df(df)
        assert_index_equal(i.data.index, idx)
        assert_frame_equal(i.data, df)

    def test_from_df_dup(self):
        idx = pd.MultiIndex.from_tuples([('foo', 0),
                                         ('foo', 0),
                                         ('foo', 2)])
        data  = [(0, 'in', 'spike'),
                 (1, 'in', 'gpot'),
                 (1, 'out', 'gpot')]
        columns = ['interface', 'io', 'type']
        df = pd.DataFrame(data, index=idx, columns=columns)
        self.assertRaises(Exception, Interface.from_df, df)

    def test_from_dict(self):
        i = Interface.from_dict({'/foo[0:3]': np.nan})
        assert_index_equal(i.data.index,
                           pd.MultiIndex.from_tuples([('foo', 0),
                                                      ('foo', 1),
                                                      ('foo', 2)]))

    def test_from_graph(self):
        i = Interface('/foo[0:3]')
        i['/foo[0]'] = [0, 'in', 'gpot']
        i['/foo[1]'] = [0, 'out', 'gpot']
        i['/foo[2]'] = [0, 'out', 'spike']
        g = nx.Graph()
        g.add_node('/foo[0]', interface=0, io='in', type='gpot')
        g.add_node('/foo[1]', interface=0, io='out', type='gpot')
        g.add_node('/foo[2]', interface=0, io='out', type='spike')
        ig = Interface.from_graph(g)
        assert_index_equal(i.data.index, ig.data.index)
        assert_frame_equal(i.data, ig.data)

    def test_is_in_interfaces(self):
        assert self.interface.is_in_interfaces('/foo[0:3]') == True
        assert self.interface.is_in_interfaces('/foo[0:4]') == False

    def test_in_ports(self):
        i = Interface('/foo[0]')
        i['/foo[0]', 'interface', 'io'] = [0, 'in']
        assert_frame_equal(self.interface.in_ports(0).data, i.data)
        assert_index_equal(self.interface.in_ports(0).index, i.index)

    def test_interface_ports(self):
        i = Interface('/foo[0:4]')
        i['/foo[0:2]', 'interface'] = 0
        i['/foo[2:4]', 'interface'] = 1
        j = Interface('/foo[2:4]')
        j['/foo[2:4]', 'interface'] = 1
        assert_frame_equal(i.interface_ports(1).data, j.data)
        assert_index_equal(i.interface_ports(1).index, j.index)

    def test_out_ports(self):
        i = Interface('/foo[1:3]')
        i['/foo[1:3]', 'interface', 'io'] = [0, 'out']
        assert_frame_equal(self.interface.out_ports(0).data, i.data)
        assert_index_equal(self.interface.out_ports(0).index, i.index)

    def test_gpot_ports(self):
        i = Interface('/foo[0:6]')
        i['/foo[0]'] = [0, 'in', 'spike']
        i['/foo[1:3]'] = [0, 'out', 'spike']
        i['/foo[3]'] = [0, 'in', 'gpot']
        i['/foo[4:6]'] = [0, 'out', 'gpot']
        j = Interface('/foo[3:6]')
        j['/foo[3]'] = [0, 'in', 'gpot']
        j['/foo[4:6]'] = [0, 'out', 'gpot']
        assert_frame_equal(i.gpot_ports(0).data, j.data)
        assert_index_equal(i.gpot_ports(0).index, j.index)

    def test_spike_ports(self):
        i = Interface('/foo[0:6]')
        i['/foo[0]'] = [0, 'in', 'spike']
        i['/foo[1:3]'] = [0, 'out', 'spike']
        i['/foo[3]'] = [0, 'in', 'gpot']
        i['/foo[4:6]'] = [0, 'out', 'gpot']
        j = Interface('/foo[0:3]')
        j['/foo[0]'] = [0, 'in', 'spike']
        j['/foo[1:3]'] = [0, 'out', 'spike']
        assert_frame_equal(i.spike_ports(0).data, j.data)
        assert_index_equal(i.spike_ports(0).index, j.index)

    def test_port_select(self):
        i = self.interface.port_select(lambda x: x[1] >= 1)
        assert_index_equal(i.data.index,
                           pd.MultiIndex.from_tuples([('foo', 1),
                                                      ('foo', 2)]))

    def test_index(self):
        assert_index_equal(self.interface.index,
                           pd.MultiIndex(levels=[['foo'], [0, 1, 2]],
                                         labels=[[0, 0, 0], [0, 1, 2]],
                                         names=['0', '1']))

    def test_interface_ids(self):
        i = Interface('/foo[0:4]')
        i['/foo[0:2]', 'interface', 'io'] = [0, 'out']
        i['/foo[2:4]', 'interface', 'io'] = [1, 'in']
        assert i.interface_ids == set([0, 1])

    def test_io_inv(self):
        i = Interface('/foo[0:4]')
        i['/foo[0:2]', 'interface', 'io'] = [0, 'out']
        i['/foo[2:4]', 'interface', 'io'] = [1, 'in']
        j = Interface('/foo[0:4]')
        j['/foo[0:2]', 'interface', 'io'] = [0, 'in']
        j['/foo[2:4]', 'interface', 'io'] = [1, 'out']
        assert_frame_equal(i.data, j.io_inv.data)

    def test_is_compatible_both_dirs(self):
        i = Interface('/foo[0:4]')
        i['/foo[0:2]', 'interface', 'io'] = [0, 'out']
        i['/foo[2:4]', 'interface', 'io'] = [0, 'in']
        j = Interface('/foo[0:4]')
        j['/foo[0:2]', 'interface', 'io'] = [1, 'in']
        j['/foo[2:4]', 'interface', 'io'] = [1, 'out']
        assert i.is_compatible(0, j, 1)

    def test_is_compatible_both_dirs_types(self):
        i = Interface('/foo[0:4]')
        i['/foo[0:2]'] = [0, 'out', 'gpot']
        i['/foo[2:4]'] = [0, 'in', 'spike']
        j = Interface('/foo[0:4]')
        j['/foo[0:2]'] = [1, 'in', 'gpot']
        j['/foo[2:4]'] = [1, 'out', 'spike']
        assert i.is_compatible(0, j, 1)

    def test_is_compatible_one_dir(self):
        i = Interface('/foo[0:2]')
        i['/foo[0:2]', 'interface', 'io'] = [0, 'out']
        j = Interface('/foo[0:2]')
        j['/foo[0:2]', 'interface', 'io'] = [1, 'in']
        assert i.is_compatible(0, j, 1)

    def test_is_compatible_one_dir_types(self):
        i = Interface('/foo[0:2]')
        i['/foo[0:2]'] = [0, 'out', 'spike']
        j = Interface('/foo[0:2]')
        j['/foo[0:2]'] = [1, 'in', 'spike']
        assert i.is_compatible(0, j, 1)

    def test_is_compatible_with_nulls(self):
        i = Interface('/foo[0:3]')
        i['/foo[0:2]', 'interface', 'io'] = [0, 'out']
        i['/foo[2]', 'interface'] = 0
        j = Interface('/foo[0:3]')
        j['/foo[0:2]', 'interface', 'io'] = [1, 'in']
        j['/foo[2]', 'interface'] = 1
        assert i.is_compatible(0, j, 1)

    def test_is_compatible_with_nulls_types(self):
        i = Interface('/foo[0:3]')
        i['/foo[0:2]'] = [0, 'out', 'gpot']
        i['/foo[2]', 'interface'] = 0
        j = Interface('/foo[0:3]')
        j['/foo[0:2]'] = [1, 'in', 'gpot']
        j['/foo[2]', 'interface'] = 1
        assert i.is_compatible(0, j, 1)

    def test_which_int_unset(self):
        i = Interface('/foo[0:4]')
        assert i.which_int('/foo[0:2]') == set()

    def test_which_int_set(self):
        i = Interface('/foo[0:4]')
        i['/foo[0]', 'interface', 'io'] = [0, 'out']
        i['/foo[1]', 'interface', 'io'] = [0, 'in']
        i['/foo[2]', 'interface', 'io'] = [1, 'in']
        i['/foo[3]', 'interface', 'io'] = [1, 'out']
        assert i.which_int('/foo[0:2]') == {0}
        assert i.which_int('/foo[0:4]') == {0, 1}