Пример #1
0
 def getMoverTableRows(self,tablerow=None,movercode=None,**kwargs):
     pkeys = tablerow['pkeys'].keys()
     table = tablerow['table']
     objtype = tablerow['objtype']
     tblobj = self.db.table(table)
     columns,mask = tblobj.rowcaptionDecode(tblobj.rowcaption)
     if columns:
         columns = ','.join(columns)
     f = tblobj.query(where='$pkey IN :pkeys',pkeys=tablerow['pkeys'].keys(),columns=columns).fetch()
     result = Bag()
     for r in f:
         result.setItem(r['pkey'],None,_pkey=r['pkey'],db_caption=tblobj.recordCaption(record=r),_customClasses='mover_db')
     indexpath = self.page.site.getStaticPath('user:temp','mover','index.xml')
     if os.path.isfile(indexpath):
         indexbag = Bag(indexpath)
         moverrows = indexbag.getItem('records.%s' %movercode)
         if not moverrows:
             return result
         for pkey in pkeys:
             rownode = moverrows.getNode(pkey)
             if rownode:
                 xml_caption=rownode.attr['caption']
                 if not pkey in result:
                     result.setItem(pkey,None,_pkey=pkey,xml_caption=xml_caption,_customClasses='mover_xml',objtype=objtype,table=tablerow['reftable'])
                 else:
                     result.getNode(pkey).attr.update(xml_caption=xml_caption,_customClasses='mover_both',objtype=objtype,table=tablerow['reftable'])
     return result
Пример #2
0
class TestAdvancedBag(unittest.TestCase):
    def setUp(self):
        self.bag = Bag()
        self.bag.setBackRef()
        self.bag["a.b.c.d"] = 4
        self.bag["a.b.e"] = 5

    def testparent(self):
        self.assertEqual(self.bag["a.b.c"].parent, self.bag["a.b"])
        c = self.bag["a.b.c"]
        self.assertEqual(c["../e"], 5)
        self.bag["a.b"].delParentRef()
        self.assertFalse(self.bag["a.b"].backref)

    def testformula(self):
        self.bag["product"] = self.bag.formula("$x*$y", x="a.b.c.d", y="a.b.e")
        self.assertEqual(self.bag["product"], self.bag["a.b.c.d"] * self.bag["a.b.e"])

        self.bag.defineFormula(calculate_perimeter="2*($base + $height)")
        self.bag.defineSymbol(base="a.b.c.d", height="a.b.e")
        self.bag["perimeter"] = self.bag.formula("calculate_perimeter")
        self.assertEqual(self.bag["perimeter"], 18)

    def testcallbackitem(self):
        def hello():
            return "Hello!"

        self.bag.setCallBackItem("say_hello", hello)
        self.assertEqual(self.bag["say_hello"], hello())

    def testnodetrigger(self):
        self.lastupdates = []

        def mycallback(node, info=None, evt=None):
            self.lastupdates.append((node.getLabel(), info, node.getValue()))

        self.bag.getNode("a.b.c.d").subscribe("lastupdates", mycallback)
        self.bag["a.b.c.d"] = 20
        self.assertEqual(self.lastupdates[-1], ("d", 4, 20))

    def testbagtriggers(self):
        self.log = []

        def log_upd(node, pathlist, oldvalue, evt):
            self.log.append((".".join(pathlist), node.getValue(), oldvalue, evt))

        def log_ins(node, pathlist, ind, evt):
            self.log.append((".".join(pathlist), node.getValue(), ind, evt))

        def log_del(node, pathlist, ind, evt):
            self.log.append((".".join(pathlist), node.getValue(), ind, evt))

        self.bag.subscribe("log", update=log_upd, insert=log_ins, delete=log_del)
        self.bag["a.b.t"] = 45
        self.assertEqual(self.log[-1], ("a.b", 45, 2, "ins"))
        self.bag["a.b.t"] = 56
        self.assertEqual(self.log[-1], ("a.b.t", 56, 45, "upd_value"))
        self.bag.delItem("a.b.t")
        self.assertEqual(self.log[-1], ("a.b", 56, 2, "del"))
Пример #3
0
 def onDroppedMover(self,file_path=None):
     import tarfile
     f = tarfile.open(file_path)
     f.extractall(self.page.site.getStaticPath('user:temp'))        
     os.remove(file_path)
     indexpath = self.page.site.getStaticPath('user:temp','mover','index.xml')
     indexbag = Bag(indexpath)
     indexbag.getNode('movers').attr.update(imported=True)
     indexbag.toXml(indexpath)
Пример #4
0
 def onDroppedMover(self, file_path=None):
     import tarfile
     f = tarfile.open(file_path)
     f.extractall(self.page.site.getStaticPath('user:temp'))
     os.remove(file_path)
     indexpath = self.page.site.getStaticPath('user:temp', 'mover',
                                              'index.xml')
     indexbag = Bag(indexpath)
     indexbag.getNode('movers').attr.update(imported=True)
     indexbag.toXml(indexpath)
Пример #5
0
 def cleanUserBatches(self,user):
     if self.page.isGuest:
         return
     if not os.path.exists(self.page.userDocument('_batch_result')):
         return
     batch_results = [x for x in os.listdir(self.page.userDocument('_batch_result')) if not x.startswith('.')]
     batch_to_remove = []
     with self.page.userStore(user) as store:
         already_registered_batch = [dc.path.split('.')[2] for dc in store.datachanges if
                                     dc.path.startswith('gnr.batch')]
         for res_doc_name in batch_results:
             result_doc = Bag(self.page.userDocument('_batch_result', res_doc_name))
             resultNode = result_doc.getNode('result')
             batch_id = result_doc['batch_id']
             if not resultNode or not 'url' in resultNode.attr:
                 batch_to_remove.append(batch_id)
                 continue
             if batch_id not in already_registered_batch:
                 batch_path = 'gnr.batch.%s' % batch_id
                 newbatch = Bag(
                         dict(title=result_doc['title'], start_ts=result_doc['start_ts'], note=result_doc['note'],
                              owner_page_id=result_doc['owner_page_id']))
                 store.set_datachange(batch_path, newbatch, reason='btc_create')
                 reason = 'btc_result_doc' if result_doc['result'] else 'btc_error_doc'
                 store.set_datachange(batch_path, result_doc, reason=reason)
     if batch_to_remove:
         self.remove_batch(batch_id=batch_to_remove)
Пример #6
0
 def th_slotbar_sections(self,parent,sections=None,condition=None,condition_kwargs=None,all_begin=None,all_end=None,**kwargs):
     inattr = parent.getInheritedAttributes()    
     th_root = inattr['th_root']
     pane = parent.div(datapath='.sections.%s' %sections)
     tblobj = self.db.table(inattr['table'])
     if sections in  tblobj.model.columns and tblobj.column(sections).relatedTable() is not None:
         sectionslist = self._th_section_from_fkey(tblobj,sections,condition=condition,condition_kwargs=condition_kwargs,all_begin=all_begin,all_end=all_end)
         dflt = None
         multivalue = True
         variable_struct = False
         isMain = False
         mandatory = None
         depending_condition = False
         depending_condition_kwargs = dict()
     else:
         m = self._th_hook('sections_%s' %sections,mangler=th_root)
         sectionslist = m()
         dflt = getattr(m,'default',None)
         multivalue=getattr(m,'multivalue',False)
         isMain = getattr(m,'isMain',False)
         variable_struct = getattr(m,'variable_struct',False)
         mandatory=getattr(m,'mandatory',True)
         depending_condition = getattr(m,'_if',False)
         depending_condition_kwargs = dictExtract(dict(m.__dict__),'_if_')
     if not sectionslist:
         return
     sectionsBag = Bag()
     for i,kw in enumerate(sectionslist):
         sectionsBag.setItem(kw.get('code') or 'r_%i' %i,None,**kw)
     pane.data('.data',sectionsBag)
     if not dflt:
         dflt = sectionsBag.getNode('#0').label
     pane.data('.current',dflt)
     pane.data('.variable_struct',variable_struct)
     if multivalue and variable_struct:
         raise Exception('multivalue cannot be set with variable_struct')
     mb = pane.multiButton(items='^.data',value='^.current',multivalue=multivalue,mandatory=mandatory,
                             disabled='^.#parent.parent.grid.loadingData',**kwargs)
     parent.dataController("""var enabled = depending_condition?funcApply('return '+depending_condition,_kwargs):true;
                             genro.dom.toggleVisible(__mb,enabled)
                             SET .%s.enabled = enabled;
                             FIRE .#parent.#parent.sections_changed;
                             """ %sections,
                             __mb=mb,ss=sections,datapath='.sections',
                             depending_condition=depending_condition,_onBuilt=True,
                                     **depending_condition_kwargs)
     pane.dataController("""
         genro.assert(currentSection,'missing current section for sections %s')
         var sectionNode = sectionbag.getNode(currentSection);
         if(isMain){
             FIRE .#parent.#parent.clearStore;
             SET .#parent.#parent.excludeDraft = !sectionNode.attr.includeDraft;
         } 
         FIRE .#parent.#parent.sections_changed;
         """ %sections
         ,isMain=isMain,mb=mb,_onBuilt=True,
         currentSection='^.current',sectionbag='=.data',
         th_root=th_root)
Пример #7
0
 def getMoverTableRows(self, tablerow=None, movercode=None, **kwargs):
     pkeys = tablerow['pkeys'].keys()
     table = tablerow['table']
     objtype = tablerow['objtype']
     tblobj = self.db.table(table)
     columns, mask = tblobj.rowcaptionDecode(tblobj.rowcaption)
     if columns:
         columns = ','.join(columns)
     f = tblobj.query(where='$pkey IN :pkeys',
                      pkeys=tablerow['pkeys'].keys(),
                      columns=columns).fetch()
     result = Bag()
     for r in f:
         result.setItem(r['pkey'],
                        None,
                        _pkey=r['pkey'],
                        db_caption=tblobj.recordCaption(record=r),
                        _customClasses='mover_db')
     indexpath = self.page.site.getStaticPath('user:temp', 'mover',
                                              'index.xml')
     if os.path.isfile(indexpath):
         indexbag = Bag(indexpath)
         moverrows = indexbag.getItem('records.%s' % movercode)
         if not moverrows:
             return result
         for pkey in pkeys:
             rownode = moverrows.getNode(pkey)
             if rownode:
                 xml_caption = rownode.attr['caption']
                 if not pkey in result:
                     result.setItem(pkey,
                                    None,
                                    _pkey=pkey,
                                    xml_caption=xml_caption,
                                    _customClasses='mover_xml',
                                    objtype=objtype,
                                    table=tablerow['reftable'])
                 else:
                     result.getNode(pkey).attr.update(
                         xml_caption=xml_caption,
                         _customClasses='mover_both',
                         objtype=objtype,
                         table=tablerow['reftable'])
     return result
Пример #8
0
 def getMoverTableRows(self, tablerow=None, movercode=None, **kwargs):
     pkeys = tablerow["pkeys"].keys()
     table = tablerow["table"]
     objtype = tablerow["objtype"]
     tblobj = self.db.table(table)
     columns, mask = tblobj.rowcaptionDecode(tblobj.rowcaption)
     if columns:
         columns = ",".join(columns)
     f = tblobj.query(where="$pkey IN :pkeys", pkeys=tablerow["pkeys"].keys(), columns=columns).fetch()
     result = Bag()
     for r in f:
         result.setItem(
             r["pkey"], None, _pkey=r["pkey"], db_caption=tblobj.recordCaption(record=r), _customClasses="mover_db"
         )
     indexpath = self.page.site.getStaticPath("user:temp", "mover", "index.xml")
     if os.path.isfile(indexpath):
         indexbag = Bag(indexpath)
         moverrows = indexbag.getItem("records.%s" % movercode)
         if not moverrows:
             return result
         for pkey in pkeys:
             rownode = moverrows.getNode(pkey)
             if rownode:
                 xml_caption = rownode.attr["caption"]
                 if not pkey in result:
                     result.setItem(
                         pkey,
                         None,
                         _pkey=pkey,
                         xml_caption=xml_caption,
                         _customClasses="mover_xml",
                         objtype=objtype,
                         table=tablerow["reftable"],
                     )
                 else:
                     result.getNode(pkey).attr.update(
                         xml_caption=xml_caption,
                         _customClasses="mover_both",
                         objtype=objtype,
                         table=tablerow["reftable"],
                     )
     return result
Пример #9
0
 def extdb_getDbStructure(self,connection_params=None,project=None,package=None):
     externaldb = self.extdb_getSourceDb(connection_params)
     existing_tables = []
     if project and package:
         p = PathResolver()
         project_path = p.project_name_to_path(project)
         modelpath = os.path.join(project_path,'packages',package,'model')
         if os.path.isdir(modelpath):
             existing_tables = map(lambda r: os.path.splitext(r)[0], filter(lambda r: r.endswith('.py'), os.listdir(modelpath)))
     src = externaldb.model.src
     result = Bag()
     for pkg in src['packages'].keys():
         pkgval = Bag()
         result.setItem(pkg, pkgval,name=pkg,checked=False)
         tables = src['packages'][pkg]['tables']
         if not tables:
             continue
         tables.sort('#k')
         for table,tblattr,tblval in tables.digest('#k,#a,#v'):
             tblattr = dict(tblattr)
             tblattr['checked'] = 'disabled:on' if table.lower() in existing_tables else False
             tblattr['name'] = table
             tableval = Bag()
             pkgval.setItem(table,tableval,**tblattr)
             for column,colattr,colval in tblval['columns'].digest('#k,#a,#v'):
                 cv = dict(colattr)
                 for t,v in tblattr.items():
                     cv['table_%s' %t] = v
                 #cv['checked'] = False
                 cv['name'] = column
                 if colval:
                     relnode = colval.getNode('relation')
                     cv['relate_to'] = relnode.attr['related_column']
                 tableval.setItem(column,None,**cv)
             if tblval['indexes']:
                 for column,unique in tblval['indexes'].digest('#a.columns,#a.unique'):
                     n = tableval.getNode(column)
                     if n:
                         n.attr['is_pkey'] = column == tblattr.get('pkey')
                         n.attr['indexed'] = True
                         n.attr['unique'] = boolean(unique)
     return result
Пример #10
0
 def cleanUserBatches(self, user):
     if self.page.isGuest:
         return
     if not os.path.exists(self.page.userDocument('_batch_result')):
         return
     batch_results = [
         x for x in os.listdir(self.page.userDocument('_batch_result'))
         if not x.startswith('.')
     ]
     batch_to_remove = []
     with self.page.userStore(user) as store:
         already_registered_batch = [
             dc.path.split('.')[2] for dc in store.datachanges
             if dc.path.startswith('gnr.batch')
         ]
         for res_doc_name in batch_results:
             result_doc = Bag(
                 self.page.userDocument('_batch_result', res_doc_name))
             resultNode = result_doc.getNode('result')
             batch_id = result_doc['batch_id']
             if not resultNode or not 'url' in resultNode.attr:
                 batch_to_remove.append(batch_id)
                 continue
             if batch_id not in already_registered_batch:
                 batch_path = 'gnr.batch.%s' % batch_id
                 newbatch = Bag(
                     dict(title=result_doc['title'],
                          start_ts=result_doc['start_ts'],
                          note=result_doc['note'],
                          owner_page_id=result_doc['owner_page_id']))
                 store.set_datachange(batch_path,
                                      newbatch,
                                      reason='btc_create')
                 reason = 'btc_result_doc' if result_doc[
                     'result'] else 'btc_error_doc'
                 store.set_datachange(batch_path, result_doc, reason=reason)
     if batch_to_remove:
         self.remove_batch(batch_id=batch_to_remove)
Пример #11
0
 def makeNewPackage(self,package_name=None,name_long=None,is_main_package=None,project_name=None):
     path_resolver = PathResolver()
     project_path = path_resolver.project_name_to_path(project_name)
     packagespath = os.path.join(project_path,'packages')
     instances = os.path.join(project_path,'instances')
     sites = os.path.join(project_path,'sites')
     package_maker = PackageMaker(package_name,base_path=packagespath,helloworld=True,name_long=name_long)
     package_maker.do()
     if os.path.exists(instances):
         for d in os.listdir(instances):
             configpath = os.path.join(instances,d,'instanceconfig.xml')
             if os.path.isfile(configpath):
                 b = Bag(configpath)
                 b.setItem('packages.%s' %package_name,'')
                 b.toXml(configpath,typevalue=False,pretty=True)
     if os.path.exists(sites):
         for d in os.listdir(sites):
             configpath = os.path.join(sites,d,'siteconfig.xml')
             if os.path.isfile(configpath):
                 b = Bag(configpath)
                 n = b.getNode('wsgi')
                 n.attr['mainpackage'] = package_name
                 b.toXml(configpath,typevalue=False,pretty=True)
     return package_name
Пример #12
0
class TestAttributeBag(unittest.TestCase):
    def setUp(self):
        self.fullbag = Bag(
            {
                "office": Bag({"John": Bag(), "Frank": Bag(), "Alexandra": Bag()}),
                "friends": Bag({"Henry": Bag(), "Fred": Bag()}),
                "relatives": Bag({"Karla": Bag(), "Albert": Bag()}),
            }
        )
        self.fullbag["office"].setItem("Xavier", Bag(), fromdate="9-15-2005", role="researcher")
        self.fullbag["office"].setAttr("Frank", fromdate="3-5-1998", role="developer")
        self.fullbag["office"].setAttr("John", fromdate="2-1-1990", role="boss", age=55)

    def testattributes(self):
        self.assertEqual(self.fullbag["office"].getAttr("Xavier", "role"), "researcher")
        self.assertEqual(self.fullbag["office.Frank?a:role"], "developer")
        l = [("Frank", "developer"), ("John", "boss"), ("Alexandra", None), ("Xavier", "researcher")]
        self.failUnless(self.fullbag["office"].digest("#k,#a.role") == self.fullbag["office.?d:#k,#a.role"] == l)
        self.failUnless(
            self.fullbag["office.Xavier"] == self.fullbag["office.#3"] == self.fullbag["office.#role=researcher"]
        )

    def testBagNodes(self):
        self.fullbag.delAttr("office.John", "age")
        n = self.fullbag.getNode("office.John")
        self.assertTrue(n.hasAttr("role"))
        self.assertFalse(n.hasAttr("age"))
        self.assertEqual(n, self.fullbag.getNodeByAttr("role", "boss"))

    def testgetNodeByAttr(self):
        researcher = self.fullbag.getNodeByAttr("role", "researcher")
        self.assertEqual(researcher, self.fullbag.getNode("office.Xavier"))

    def testfromToXml(self):
        self.fullbag["relatives.Karla.birthday"] = datetime.date(1952, 12, 10)
        self.fullbag["relatives.Karla.pierciengs"] = 0
        self.fullbag["relatives.Karla.dogname"] = ""
        self.fullbag.setAttr("relatives.Karla", age=54)
        self.fullbag.toXml("mybag.xml")
        x = self.fullbag["relatives"].toXml()
        b = Bag(x)
        self.assertEqual(b.asString(), self.fullbag["relatives"].asString())

    def testsfromSource(self):
        current = os.getcwd()
        fromlocal_std = Bag("%s/test_files/standardxml.xml" % current)
        self.assertTrue(isinstance(fromlocal_std, Bag))
        # non riesce a printarla per carattere non encodabile
        fromlocal_bag = Bag("%s/test_files/mybag.xml" % current)
        self.assertTrue(isinstance(fromlocal_bag, Bag))
        # uncomment the following test if you are online
        # fromurl=Bag('http://www.plone.org')
        # self.assertTrue(isinstance(fromurl, Bag))
        stringxml = '<?xml version="1.02" encoding="UTF-8"?><a><b name="fuffy"><d>dog</d></b><c/></a>'
        fromstringxml = Bag(stringxml)
        self.assertTrue(isinstance(fromstringxml, Bag))
        fromdirectory = Bag("%s/test_files" % current)
        self.assertTrue(isinstance(fromdirectory, Bag))

    def testmerge(self):
        newbag = Bag()
        newbag.setItem("Henry", self.fullbag["friends.Henry"], role="documentation and tests")
        newbag.setItem("Xavier", "Mr Xavier", role="documentation manager", age=26)
        allflagstrue = self.fullbag["office"].merge(newbag)  # all flags true
        allflagsfalse = self.fullbag["office"].merge(
            newbag, upd_values=False, add_values=False, upd_attr=False, add_attr=False
        )
        self.assertEqual(allflagsfalse.asString(), self.fullbag["office"].asString())
        notupdatevalues = self.fullbag["office"].merge(newbag, upd_values=False)
        self.assertTrue(isinstance(self.fullbag["office.Xavier"], Bag))
        notaddvalues = self.fullbag["office"].merge(newbag, add_values=False)
        self.assertEqual(len(self.fullbag["office"].items()), len(notaddvalues.items()))
        notupdateattrs = self.fullbag["office"].merge(newbag, upd_attr=False)
        self.assertEqual(self.fullbag["office.Xavier?a:role"], notupdateattrs["Xavier?a:role"])
        notaddattrs = self.fullbag["office"].merge(newbag, add_attr=False)
        self.assertFalse(notaddattrs.getAttr("Xavier", "age", default=False))

    def testsum(self):
        numbers = Bag()
        numbers.setItem("first", 20, height=22)
        numbers.setItem("second", 30, height=342)
        self.assertEqual(numbers.sum("#v,#a.height"), [50, 364])
Пример #13
0
class TestAdvancedBag(unittest.TestCase):
    def setUp(self):
        self.bag = Bag()
        self.bag.setBackRef()
        self.bag['a.b.c.d'] = 4
        self.bag['a.b.e'] = 5

    def testparent(self):
        self.assertEqual(self.bag['a.b.c'].parent, self.bag['a.b'])
        c = self.bag['a.b.c']
        self.assertEqual(c['../e'], 5)
        self.bag['a.b'].delParentRef()
        self.assertFalse(self.bag['a.b'].backref)

    def testformula(self):
        self.bag['product'] = self.bag.formula('$x*$y', x='a.b.c.d', y='a.b.e')
        self.assertEqual(self.bag['product'],
                         self.bag['a.b.c.d'] * self.bag['a.b.e'])

        self.bag.defineFormula(calculate_perimeter='2*($base + $height)')
        self.bag.defineSymbol(base='a.b.c.d', height='a.b.e')
        self.bag['perimeter'] = self.bag.formula('calculate_perimeter')
        self.assertEqual(self.bag['perimeter'], 18)

    def testcallbackitem(self):
        def hello():
            return 'Hello!'

        self.bag.setCallBackItem('say_hello', hello)
        self.assertEqual(self.bag['say_hello'], hello())

    def testnodetrigger(self):
        self.lastupdates = []

        def mycallback(node, info=None, evt=None):
            self.lastupdates.append((node.getLabel(), info, node.getValue()))

        self.bag.getNode('a.b.c.d').subscribe('lastupdates', mycallback)
        self.bag['a.b.c.d'] = 20
        self.assertEqual(self.lastupdates[-1], ('d', 4, 20))

    def testbagtriggers(self):
        self.log = []

        def log_upd(node, pathlist, oldvalue, evt):
            self.log.append(
                ('.'.join(pathlist), node.getValue(), oldvalue, evt))

        def log_ins(node, pathlist, ind, evt):
            self.log.append(('.'.join(pathlist), node.getValue(), ind, evt))

        def log_del(node, pathlist, ind, evt):
            self.log.append(('.'.join(pathlist), node.getValue(), ind, evt))

        self.bag.subscribe('log',
                           update=log_upd,
                           insert=log_ins,
                           delete=log_del)
        self.bag['a.b.t'] = 45
        self.assertEqual(self.log[-1], ('a.b', 45, 2, 'ins'))
        self.bag['a.b.t'] = 56
        self.assertEqual(self.log[-1], ('a.b.t', 56, 45, 'upd_value'))
        self.bag.delItem('a.b.t')
        self.assertEqual(self.log[-1], ('a.b', 56, 2, 'del'))
Пример #14
0
class TestAttributeBag(unittest.TestCase):
    def setUp(self):
        self.fullbag = Bag({
            'office':
            Bag({
                'John': Bag(),
                'Frank': Bag(),
                'Alexandra': Bag()
            }),
            'friends':
            Bag({
                'Henry': Bag(),
                'Fred': Bag()
            }),
            'relatives':
            Bag({
                'Karla': Bag(),
                'Albert': Bag()
            })
        })
        self.fullbag['office'].setItem('Xavier',
                                       Bag(),
                                       fromdate='9-15-2005',
                                       role='researcher')
        self.fullbag['office'].setAttr('Frank',
                                       fromdate='3-5-1998',
                                       role='developer')
        self.fullbag['office'].setAttr('John',
                                       fromdate='2-1-1990',
                                       role='boss',
                                       age=55)

    def testattributes(self):
        self.assertEqual(self.fullbag['office'].getAttr('Xavier', 'role'),
                         'researcher')
        self.assertEqual(self.fullbag['office.Frank?a:role'], 'developer')
        l = [('Frank', 'developer'), ('John', 'boss'), ('Alexandra', None),
             ('Xavier', 'researcher')]
        self.failUnless(self.fullbag['office'].digest('#k,#a.role') ==
                        self.fullbag['office.?d:#k,#a.role'] == l)
        self.failUnless(
            self.fullbag['office.Xavier'] == self.fullbag['office.#3'] ==
            self.fullbag['office.#role=researcher'])

    def testBagNodes(self):
        self.fullbag.delAttr('office.John', 'age')
        n = self.fullbag.getNode('office.John')
        self.assertTrue(n.hasAttr('role'))
        self.assertFalse(n.hasAttr('age'))
        self.assertEqual(n, self.fullbag.getNodeByAttr('role', 'boss'))

    def testgetNodeByAttr(self):
        researcher = self.fullbag.getNodeByAttr('role', 'researcher')
        self.assertEqual(researcher, self.fullbag.getNode('office.Xavier'))

    def testfromToXml(self):
        self.fullbag['relatives.Karla.birthday'] = datetime.date(1952, 12, 10)
        self.fullbag['relatives.Karla.pierciengs'] = 0
        self.fullbag['relatives.Karla.dogname'] = ''
        self.fullbag.setAttr('relatives.Karla', age=54)
        self.fullbag.toXml('mybag.xml')
        x = self.fullbag['relatives'].toXml()
        b = Bag(x)
        self.assertEqual(b.asString(), self.fullbag['relatives'].asString())

    def testsfromSource(self):
        current = os.getcwd()
        fromlocal_std = Bag('%s/test_files/standardxml.xml' % current)
        self.assertTrue(isinstance(fromlocal_std, Bag))
        #non riesce a printarla per carattere non encodabile
        fromlocal_bag = Bag('%s/test_files/mybag.xml' % current)
        self.assertTrue(isinstance(fromlocal_bag, Bag))
        #uncomment the following test if you are online
        #fromurl=Bag('http://www.plone.org')
        #self.assertTrue(isinstance(fromurl, Bag))
        stringxml = '<?xml version="1.02" encoding="UTF-8"?><a><b name="fuffy"><d>dog</d></b><c/></a>'
        fromstringxml = Bag(stringxml)
        self.assertTrue(isinstance(fromstringxml, Bag))
        fromdirectory = Bag('%s/test_files' % current)
        self.assertTrue(isinstance(fromdirectory, Bag))

    def testmerge(self):
        newbag = Bag()
        newbag.setItem('Henry',
                       self.fullbag['friends.Henry'],
                       role='documentation and tests')
        newbag.setItem('Xavier',
                       'Mr Xavier',
                       role='documentation manager',
                       age=26)
        allflagstrue = self.fullbag['office'].merge(newbag)  #all flags true
        allflagsfalse = self.fullbag['office'].merge(newbag,
                                                     upd_values=False,
                                                     add_values=False,
                                                     upd_attr=False,
                                                     add_attr=False)
        self.assertEqual(allflagsfalse.asString(),
                         self.fullbag['office'].asString())
        notupdatevalues = self.fullbag['office'].merge(newbag,
                                                       upd_values=False)
        self.assertTrue(isinstance(self.fullbag['office.Xavier'], Bag))
        notaddvalues = self.fullbag['office'].merge(newbag, add_values=False)
        self.assertEqual(len(self.fullbag['office'].items()),
                         len(notaddvalues.items()))
        notupdateattrs = self.fullbag['office'].merge(newbag, upd_attr=False)
        self.assertEqual(self.fullbag['office.Xavier?a:role'],
                         notupdateattrs['Xavier?a:role'])
        notaddattrs = self.fullbag['office'].merge(newbag, add_attr=False)
        self.assertFalse(notaddattrs.getAttr('Xavier', 'age', default=False))

    def testsum(self):
        numbers = Bag()
        numbers.setItem('first', 20, height=22)
        numbers.setItem('second', 30, height=342)
        self.assertEqual(numbers.sum('#v,#a.height'), [50, 364])