示例#1
0
    def test_private_events(self):
        event_log = []
        def record(context):
            event_log.append((context.obj, context.action, context.val))

        p = odml.Property(name="p", value="1")
        p.add_change_handler(record)
        p.value = "2"
        p.value = "1"

        log1 = event_log
        event_log = []

        pp = proxy.PropertyProxy(p)
        pp.value = "2"
        pp.value = "1"

        self.assertEqual(log1, event_log)

        p.remove_change_handler(record)
        pp.add_change_handler(record)
        event_log = []

        pp.value = "2"
        pp.value = "1"

        self.assertEqual(log1, event_log)
示例#2
0
    def test_section_events(self):
        s = odml.Section("sec1")
        p = odml.Property(name="p", value="1")
        s.append(p)

        event_log = []
        def record(context):
            event_log.append((context.obj, context.action, context.val))

        s.add_change_handler(record)
        p.value = "2"
        p.value = "1"

        log1 = event_log
        event_log = []

        s.remove_change_handler(record)

        ps = proxy.NonexistantSection("psec")
        pp = proxy.PropertyProxy(p)
        ps.append(pp)

        ps.add_change_handler(record)
        p.value = "2"
        p.value = "1"
        self.assertEqual(log1, event_log)
示例#3
0
    def test_proxy_equality(self):
        p = odml.Property(name="p", value="1")
        pp = proxy.PropertyProxy(p)
        self.assertTrue(p == pp)

        s = odml.Section(name="sec1")
        ps = proxy.MappedSection(s)
        s.append(p)
        self.assertEqual(s, ps)
示例#4
0
    def test_section_proxy(self):
        s = odml.Section("sec1")
        p = odml.Property(name="p", value="1")
        s.append(p)

        ps = proxy.MappedSection(s)

        # forward attributes
        ps.name = "sec2"
        self.assertEqual(s.name, "sec2")

        p2 = odml.Property(name="p2", value="2")

        # append to proxy section, creates a proxy in ps
        # and the original object in s
        ps.append(p2)

        self.assertIn(p2, s)
        self.assertIn(p2, ps)
        self.assertIs(s.contains(p2), p2)
        self.assertIsInstance(ps.contains(p2), proxy.Proxy)

        # removing from proxy section, removes both
        ps.remove(p2)
        self.assertNotIn(p2, s)
        self.assertNotIn(p2, ps)

        # appending to section, creates a proxy in ps
        s.append(p2)
        self.assertIn(p2, s)
        self.assertIn(p2, ps)
        self.assertIs(s.contains(p2), p2)
        self.assertIsInstance(ps.contains(p2), proxy.Proxy)

        # removing removes from ps too
        s.remove(p2)
        self.assertNotIn(p2, s)
        self.assertNotIn(p2, ps)

        # appending creates in both, removing in ps removes in both
        s.append(p2)
        ps.remove(p2)
        self.assertNotIn(p2, s)
        self.assertNotIn(p2, ps)

        # append a proxy to ps, both original and proxy compare to
        # be 'in' ps
        pp = proxy.PropertyProxy(p)
        # you can use proxy_append to add an explicit proxy obj (without affecting
        # the original section) or you can append the object to the original section
        # so that the proxy object is created in the proxy section, too
        ps.proxy_append(pp) # this one is only in ps
        self.assertIn(pp, ps)
        self.assertIn(p, ps) # as p == pp, this also holds true

        # even if the name is changed
        ps.name = "p3"
        self.assertEqual(p.name, "p") # does not change the name of p
        self.assertEqual(ps.name, "p3") # but the one of ps

        self.assertIn(pp, ps) # both are in ps though
        self.assertIn(p, ps)

        # and we can remove it again
        ps.remove(p)
        self.assertNotIn(p, ps)
        self.assertNotIn(pp, ps)
        self.assertNotIn(p, s)

        s2 = odml.Section("sec3")
        # a mapped section added to another mapped section
        # will only appear there
        ps2 = proxy.MappedSection(s2)
        ps.proxy_append(ps2)

        self.assertIn(ps2, ps)
        self.assertIn(s2, ps)
        self.assertNotIn(s2, s)

        # and we can remove it again
        ps.remove(s2)
        self.assertNotIn(ps2, ps)
示例#5
0
def create_property_mapping(sec, prop):
    """
    map a property to its destination place using the mapping rules (see test/mapping.py)

    Note: all sections of the document need already to be mapped
    """
    msec = sec._active_mapping
    mprop = proxy.PropertyProxy(prop)
    mprop._section = None
    prop._active_mapping = mprop

    mapping = prop.mapped_object
    if mapping is None:  # easy case: just proxy the property
        msec.proxy_append(mprop)
        return

    mprop.name = mapping.name

    dst_type = mapping._section.type

    # rule 4c: target-type == section-type
    #          copy attributes, keep property
    if dst_type == msec.type:
        msec.proxy_append(mprop)
        return mprop

    # rule 4d: one child has the type
    child = msec.find_related(type=dst_type,
                              siblings=False,
                              parents=False,
                              findAll=True)
    if child is None:
        # rule 4e: a sibling has the type
        sibling = msec.find_related(type=dst_type,
                                    children=False,
                                    parents=False)
        if sibling is not None:
            rel = sibling.find_related(type=msec.type, findAll=True)
            if len(rel) > 1:
                # rule 4e2: create a subsection linked to the sibling
                # TODO set repository and other attributes?
                child = proxy.NonexistantSection(sibling.name, sibling.type)
                child.proxy_append(mprop)
                msec.proxy_append(child)

                # TODO the link will have trouble to be resolved, as the
                # nonexistant section does not allow to create any attributes in it
                # as it cannot be proxied
                child._link = sibling.get_path()
                return mprop
            # rule 4e1: exactly one relation for sibling
            child = sibling  # once we found the target section, the code stays the same
        else:
            # rule 4f: no sibling, create a new section
            # TODO set repository and other attributes?
            child = proxy.NonexistantSection(mapping._section.name, dst_type)
            msec.proxy_append(child)
    elif len(child) > 1:
        raise MappingError("""Your data organisation does not make sense,
        there are %d children of type '%s'. Don't know how to handle.""" %
                           (len(child), dst_type))
    else:  # exactly one child found
        child = child[0]

    # corner-case: we are remapping and/or the section already contains a property
    # with the same name
    # however this will also hold true, if multiple properties map to the same target
    # for now live with it being there multiple times (TODO)
    obj = child.contains(mprop)
    if obj is not None:
        pass  #child.proxy_remove(obj)

    child.proxy_append(mprop)
    return mprop