# -*- coding: utf-8 -*-

node.utils
==========

Zodict
------

Test Zodict::

    >>> from zope.interface.common.mapping import IFullMapping
    >>> from node.utils import Zodict
    >>> Zodict
    <class 'node.utils.Zodict'>
    
    >>> zod = Zodict()
    >>> IFullMapping.providedBy(zod)
    True
    
    ### XXX: all interface methods there.

ReverseMapping::

    >>> from node.utils import ReverseMapping
    >>> context = {
    ...     'foo': 'a',
    ...     'bar': 'b',
    ... }
    >>> mapping = ReverseMapping(context)

    >>> [v for v in mapping]
    ['a', 'b']

    >>> mapping.keys()
    ['a', 'b']
    
    >>> mapping.values()
    ['foo', 'bar']
    
    >>> mapping.items()
    [('a', 'foo'), ('b', 'bar')]
    
    >>> len(mapping)
    2
    
    >>> 'a' in mapping
    True
    
    >>> 'foo' in mapping
    False
    
    >>> mapping['a']
    'foo'
    
    >>> mapping['foo']
    Traceback (most recent call last):
      ...
    KeyError: 'foo'
    
    >>> mapping.get('b')
    'bar'
    
    >>> mapping.get('foo', 'DEFAULT')
    'DEFAULT'

AttributeAccess::

    >>> from node.utils import AttributeAccess
    >>> attraccess = AttributeAccess(context)
    >>> attraccess.foo
    'a'
    
    >>> attraccess.a
    Traceback (most recent call last):
      ...
    AttributeError: a
    
    >>> attraccess.foo = 'foo'
    >>> attraccess.foo
    'foo'
    
    >>> attraccess['foo']
    'foo'
    
    >>> attraccess['baz'] = 'bla'
    >>> attraccess.baz
    'bla'
    
    >>> del attraccess['bar']
    >>> object.__getattribute__(attraccess, 'context').keys()
    ['baz', 'foo']

    >>> attraccess.x = 0
    >>> object.__getattribute__(attraccess, 'context').keys()
    ['baz', 'foo', 'x']

StrCodec decode and encode::

    >>> from node.utils import (
    ...     StrCodec,
    ...     encode,
    ...     decode,
    ... )
    >>> encode(u'\xe4')
    '\xc3\xa4'
    
    >>> encode([u'\xe4'])
    ['\xc3\xa4']
    
    >>> encode({u'\xe4': u'\xe4'})
    {'\xc3\xa4': '\xc3\xa4'}
    
    >>> encode('\xc3\xa4')
    '\xc3\xa4'
    
    >>> decode('foo')
    u'foo'
    
    >>> decode(('foo', 'bar'))
    (u'foo', u'bar')
    
    >>> decode({'foo': 'bar'})
    {u'foo': u'bar'}
    
    >>> decode('fo\xe4')
    'fo\xe4'
    
    >>> codec = StrCodec(soft=False)
    >>> codec.decode('fo\xe4')
    Traceback (most recent call last):
      ...
    UnicodeDecodeError: 'utf8' codec can't decode byte 0xe4 in position 2: 
    unexpected end of data
