Example #1
0
 def test_ls_dotfile(self):
     "Shouldn't see dotfiles"
     nix.touch(Path(self.tdir) + '.dotrc')
     self.assertTrue(os.path.isfile(self.tdir + '/.dotrc'))
     contents = nix.ls(Path(self.tdir))
     contents.sort()
     self.assertEqual(['bar.txt', 'foo.txt'], contents)
Example #2
0
 def test_recursive_contents(self):
     """
     This was caused by ending up with a Path as _value, not catching it in __init__.
     """
     p = Path(self.tdir) + 'some.txt'
     p.touch()
     p2 = Path(p)
     self.assertEqual('', p2.contents)
Example #3
0
    def test_mv_target_exists(self):
        "Should just overwrite"
        one = Path(str(self.tpath) + '//one.txt')
        two = Path(str(self.tpath) + '//two.txt')
        one << 'Contentz'
        two << 'Contentz Two'

        target = str(two)

        self.assertTrue(os.path.exists(target))
        nix.mv(str(one), target)
        self.assertTrue(os.path.exists(target))
        self.assertFalse(os.path.exists(str(one)))
        self.assertEqual('Contentz', two.contents)
Example #4
0
 def test_ls_almost_all(self):
     "Should see most dotfiles"
     nix.touch(Path(self.tdir) + '.dotrc')
     self.assertTrue(os.path.isfile(self.tdir + '/.dotrc'))
     contents = nix.ls(self.tdir, almost_all=True)
     contents.sort()
     self.assertEqual(['.dotrc', 'bar.txt', 'foo.txt'], contents)
Example #5
0
 def test_ls_a_ignore_backups(self):
     "Should ignore ~ files even with all"
     nix.touch(Path(self.tdir) + 'dotrc~')
     self.assertTrue(os.path.isfile(self.tdir + '/dotrc~'))
     contents = nix.ls(self.tdir, ignore_backups=True, all=True)
     contents.sort()
     self.assertEqual(['.', '..', 'bar.txt', 'foo.txt'], contents)
Example #6
0
 def test_accepts_path(self):
     "Should Duck-type with Path objects"
     nix.cd(Path('/tmp'))
     cwd = os.getcwd()
     if sys.platform == 'darwin':
         cwd = cwd.replace('/private', '')
     self.assertEqual('/tmp', cwd)
Example #7
0
 def test_ln_path(self):
     "Should link path objects"
     dest = Path(self.tdir)
     dest += 'hardlink'
     nix.ln(self.src, dest)
     self.assertTrue(os.path.isfile(str(dest)))
     self.assertTrue(filecmp.cmp(self.src, str(dest)))
     self.assertFalse(os.path.islink(str(dest)))
Example #8
0
File: nix.py Project: Edoi1/MASTER1
    def __enter__(self):
        """
        Contextmanager protocol initialization.

        Returns a Path representing the current working directory
        """
        from ffs import Path
        return Path(self.path)
Example #9
0
 def test_force(self):
     "Force for non-empty dest"
     dest = Path(self.tdir) + 'hardlink'
     dest << 'contentz'
     self.assertEqual('contentz', dest.contents)
     nix.ln(self.src, dest, force=True)
     self.assertNotEqual('contentz', dest.contents)
     self.assertTrue(os.path.isfile(str(dest)))
     self.assertTrue(filecmp.cmp(self.src, str(dest)))
     self.assertFalse(os.path.islink(str(dest)))
Example #10
0
class CPTestCase(unittest.TestCase):
    def setUp(self):
        self.tdir = Path(tempfile.mkdtemp())

    def tearDown(self):
        if os.path.exists(self.tdir):
            shutil.rmtree(self.tdir)

    def test_cp_file(self):
        "Copy self to dest"
        f1 = self.tdir / 'one.txt'
        f2 = self.tdir + 'two.txt'
        f1 << 'Contents!'
        nix.cp(f1, f2)
        self.assertTrue(filecmp.cmp(f1, f2, False))

    def test_cp_dir(self):
        "Is a no-op"
        self.tdir.mkdir('this')
        p = self.tdir / 'that'
        nix.cp(self.tdir / 'this', p)
        self.assertFalse(p)

    def test_cp_file_recursive(self):
        "Recursive does nothing"
        f1 = self.tdir / 'one.txt'
        f2 = self.tdir + 'two.txt'
        f1 << 'Contents!'
        nix.cp(f1, f2, recursive=True)
        self.assertTrue(filecmp.cmp(f1, f2, False))

    def test_cp_dir_recursive(self):
        "Should copy the tree"
        d1 = self.tdir / 'this'
        d2 = self.tdir / 'that'
        d1.touch('one.txt', 'two.txt')
        self.tdir.mkdir('this')
        nix.cp(d1, d2, recursive=True)
        self.assertEqual([], filecmp.dircmp(d1, d2).diff_files)

    def test_cp_nonexistant(self):
        "Should raise"
        with self.assertRaises(exceptions.DoesNotExistError):
            nix.cp(self.tdir + 'whatever', self.tdir + 'whateverer')

    def test_cp_target_exists(self):
        "Should raise"
        with self.assertRaises(exceptions.ExistsError):
            self.tdir.touch('whatever', 'whateverer')
            nix.cp(self.tdir + 'whatever', self.tdir + 'whateverer')
Example #11
0
class CPTestCase(unittest.TestCase):
    def setUp(self):
        self.tdir = Path(tempfile.mkdtemp())

    def tearDown(self):
        if os.path.exists(self.tdir):
            shutil.rmtree(self.tdir)

    def test_cp_file(self):
        "Copy self to dest"
        f1 = self.tdir / 'one.txt'
        f2 = self.tdir + 'two.txt'
        f1 << 'Contents!'
        nix.cp(f1, f2)
        self.assertTrue(filecmp.cmp(f1, f2, False))

    def test_cp_dir(self):
        "Is a no-op"
        self.tdir.mkdir('this')
        p = self.tdir / 'that'
        nix.cp(self.tdir / 'this', p)
        self.assertFalse(p)

    def test_cp_file_recursive(self):
        "Recursive does nothing"
        f1 = self.tdir / 'one.txt'
        f2 = self.tdir + 'two.txt'
        f1 << 'Contents!'
        nix.cp(f1, f2, recursive=True)
        self.assertTrue(filecmp.cmp(f1, f2, False))

    def test_cp_dir_recursive(self):
        "Should copy the tree"
        d1 = self.tdir / 'this'
        d2 = self.tdir / 'that'
        d1.touch('one.txt', 'two.txt')
        self.tdir.mkdir('this')
        nix.cp(d1, d2, recursive=True)
        self.assertEqual([], filecmp.dircmp(d1, d2).diff_files)

    def test_cp_nonexistant(self):
        "Should raise"
        with self.assertRaises(exceptions.DoesNotExistError):
            nix.cp(self.tdir + 'whatever', self.tdir + 'whateverer')

    def test_cp_target_exists(self):
        "Should raise"
        with self.assertRaises(exceptions.ExistsError):
            self.tdir.touch('whatever', 'whateverer')
            nix.cp(self.tdir + 'whatever', self.tdir + 'whateverer')
Example #12
0
 def test_mkdir_path(self):
     "Should make a directory from a Path()"
     self.assertFalse(os.path.exists(self.nodir))
     nix.mkdir(Path(self.nodir))
     self.assertTrue(os.path.exists(self.nodir))
Example #13
0
    def test_creates_zipfile(self):
        "create a zip archive if one doesn't exist."
        with Path.temp() as tmp:
            created = archive.ZipPath(tmp/'my.zip')

            self.assertTrue(zipfile.is_zipfile(str(tmp/'my.zip')))
Example #14
0
 def test_not_a_tarfile_raises(self):
     "Should raise"
     with Path.tempfile() as temp:
         with self.assertRaises(exceptions.NotATarFileError):
             fs = archive.TarFilesystem(temp)
Example #15
0
 def setUp(self):
     self.tdir = Path(tempfile.mkdtemp())
Example #16
0
 def test_touch_path(self):
     "Create from a Path object"
     filestr = self.tdir + '/foo.txt'
     filepath = Path(filestr)
     nix.touch(filepath)
     self.assertTrue(os.path.isfile(filestr))
Example #17
0
Unittests for the ffs.contrib.archive module
"""
import sys
import tarfile
import tempfile
import unittest
import zipfile

from mock import MagicMock, patch

if sys.version_info <  (2, 7): import unittest2 as unittest

from ffs import exceptions, Path, rm, touch
from ffs.contrib import archive

HERE = Path.here()
FIXTURES = HERE / 'fixtures'

class TarFilesystemTestCase(unittest.TestCase):
    def setUp(self):
        self.fs = archive.TarFilesystem(FIXTURES/'simple.tar')

    def tearDown(self):
        pass

    def test_not_a_tarfile_raises(self):
        "Should raise"
        with Path.tempfile() as temp:
            with self.assertRaises(exceptions.NotATarFileError):
                fs = archive.TarFilesystem(temp)
Example #18
0
 def test_mkdirp_path(self):
     "Should accept Path objects"
     p = Path(self.nopath) + 'some/long/structure'
     nix.mkdir_p(p)
     self.assertTrue(os.path.isdir(self.nopath + '/some/long/structure'))
Example #19
0
 def test_with_path(self):
     "Should work with Path objects"
     nix.chmod(Path(self.tname), 644)
     self.assertEqual(33412, os.stat(self.tname).st_mode)
Example #20
0
 def test_path(self):
     "Should take Path objects"
     expected = "\n".join([str(x) for x in range(10)]) + "\n"
     frist = nix.head(Path(self.tname))
     self.assertEqual(expected, frist)
Example #21
0
 def setUp(self):
     self.tdir = Path(tempfile.mkdtemp())
Example #22
0
 def test_chown_path(self):
     "Can we chown a path?"
     with patch.object(nix.os, 'chown') as pchown:
         nix.chown(Path('/hai'), uid=100)
         pchown.assert_called_once_with('/hai', 100, -1)
Example #23
0
 def test_mkdir_parents(self):
     "make all parent dirs"
     self.assertFalse(os.path.exists(self.nodir))
     p = Path(self.nodir) + 'child/leaves'
     nix.mkdir(p, parents=True)
     self.assertTrue(os.path.exists(self.nodir))
Example #24
0
 def test_div_unicode_withformatting(self):
     "Should just join the paths."
     p = Path('/tmp')
     p = p / six.u('foo') / '{0}.xml'.format(six.u('bar'))
     self.assertEqual('/tmp/foo/bar.xml', p)
Example #25
0
 def test_mkdir_parents_false(self):
     "Should raise"
     self.assertFalse(os.path.exists(self.nodir))
     p = Path(self.nodir) + 'child/leaves'
     with self.assertRaises(exceptions.BadParentingError):
         nix.mkdir(p, parents=False)
Example #26
0
 def setUp(self):
     self.tfile = tempfile.mktemp()
     self.tcsv = Path(self.tfile)
     self.tcsv << '1,2,3,4'
Example #27
0
 def setUp(self):
     self.tpath = Path(tempfile.mkdtemp())
Example #28
0
 def setUp(self):
     self.tfile = tempfile.mktemp()
     self.tcsv = Path(self.tfile)
     self.tcsv << '1,2,3,4'
Example #29
0
 def test_rm_path(self):
     "Remove a Path"
     self.assertTrue(os.path.exists(self.newfile))
     nix.rm(Path(self.newfile))
     self.assertFalse(os.path.exists(self.newfile))
Example #30
0
class CSVTestCase(unittest.TestCase):
    def setUp(self):
        self.tfile = tempfile.mktemp()
        self.tcsv = Path(self.tfile)
        self.tcsv << '1,2,3,4'

    def test_repr(self):
        with self.tcsv.csv() as acsv:
            rep = '<Unresolved CSV {0}>'.format(self.tfile)
            self.assertEqual(rep, acsv.__repr__())

    def test_resolve_reader(self):
        "Resolve to a reader"
        with self.tcsv.csv() as acsv:
            self.assertIsInstance(acsv, formats.CSV)
            self.assertEqual(None, acsv.resolved)
            self.assertEqual(None, acsv.fh)
            iterable = acsv._resolve_reader()
            self.assertIsInstance(acsv.resolved, ReaderType)
            self.assertIsInstance(acsv.fh, file)
            self.assertEqual('rU', acsv.fh.mode)

    def test_reader_delimiter(self):
        "Should pass through"
        with self.tcsv.csv(delimiter='|') as acsv:
            with patch('csv.reader') as pread:
                acsv._resolve_reader()
                pread.assert_called_with(acsv.fh, delimiter='|')

    def test_resolve_writer(self):
        "Resolve to a writer"
        with self.tcsv.csv() as acsv:
            self.assertIsInstance(acsv, formats.CSV)
            self.assertEqual(None, acsv.resolved)
            self.assertEqual(None, acsv.fh)
            iterable = acsv._resolve_writer()
            self.assertIsInstance(acsv.resolved, WriterType)
            self.assertIsInstance(acsv.fh, file)
            self.assertEqual('w', acsv.fh.mode)

    def test_writer_delimiter(self):
        "Should pass through"
        with self.tcsv.csv(delimiter='|') as acsv:
            with patch('csv.writer') as pread:
                acsv._resolve_writer()
                pread.assert_called_with(acsv.fh, delimiter='|')

    def test_iter(self):
        "Iterate through rows"
        with self.tcsv.csv() as acsv:
            for i, row in enumerate(acsv):
                self.assertEqual(0, i)
                self.assertEqual(row, '1 2 3 4'.split())

    def test_iter_resolves(self):
        "Iterating should make us a reader"
        with self.tcsv.csv() as acsv:
            with patch.object(acsv, '_resolve_reader') as pres:
                iterable = acsv.__iter__()
                pres.assert_called_with()

    def test_iter_raises(self):
        "If we've resolved to a writer, raise"
        with self.tcsv.csv() as acsv:
            acsv._resolve_writer()
            with self.assertRaises(TypeError):
                acsv.__iter__()

    def test_next(self):
        "Next on the generator-like reader"
        with self.tcsv.csv() as acsv:
            self.assertEqual(acsv.next(), '1 2 3 4'.split())

    def test_next_resolves(self):
        "Nextating should make us a reader"
        with self.tcsv.csv() as acsv:
            with patch.object(acsv, '_resolve_reader') as pres:
                pres.side_effect = lambda: setattr(acsv, 'resolved', MagicMock(
                ))
                nxt = acsv.next()
                pres.assert_called_with()

    def test_next_raises(self):
        "If we've resolved to a wrnext, raise"
        with self.tcsv.csv() as acsv:
            acsv._resolve_writer()
            with self.assertRaises(AttributeError):
                acsv.next()

    def test_line_num_resolves(self):
        "Line num should resolve"
        with self.tcsv.csv() as acsv:
            with patch.object(acsv, '_resolve_reader') as pres:
                pres.side_effect = lambda: setattr(acsv, 'resolved', MagicMock(
                ))
                n = acsv.line_num
                pres.assert_called_with()

    def test_line_num_passes_through(self):
        "Line num should pass through"
        with self.tcsv.csv() as acsv:
            with patch('csv.reader') as pread:
                pread.return_value.line_num = 576
                n = acsv.line_num
                self.assertEqual(576, n)

    def test_line_num_raises(self):
        "If we're resolved to a writer, raise"
        with self.tcsv.csv() as acsv:
            acsv._resolve_writer()
            with self.assertRaises(AttributeError):
                n = acsv.line_num

    def test_writerow(self):
        "Write a row"
        with self.tcsv.csv() as acsv:
            acsv.writerow([1, 2, 3, 4])
        self.assertEqual('1,2,3,4\r\n', self.tcsv.contents)

    def test_writerow_resolves(self):
        "Iterating should make us a reader"
        with self.tcsv.csv() as acsv:
            with patch.object(acsv, '_resolve_writer') as pres:
                pres.side_effect = lambda: setattr(acsv, 'resolved', MagicMock(
                ))
                iterable = acsv.writerow([1, 3])
                pres.assert_called_with()

    def test_writerow_raises(self):
        "If we're resolved to a reader, raise"
        with self.tcsv.csv() as acsv:
            acsv._resolve_reader()
            with self.assertRaises(AttributeError):
                acsv.writerow([1, 2])

    def test_writerows_raises(self):
        "If we're resolved to a reader, raise"
        with self.tcsv.csv() as acsv:
            acsv._resolve_reader()
            with self.assertRaises(AttributeError):
                acsv.writerows([1, 2])

    def test_writerows(self):
        "Write a row"
        with self.tcsv.csv() as acsv:
            acsv.writerows([[1, 2], [3, 4]])
        self.assertEqual('1,2\r\n3,4\r\n', self.tcsv.contents)

    def test_writerows_resolves(self):
        "Iterating should make us a reader"
        with self.tcsv.csv() as acsv:
            with patch.object(acsv, '_resolve_writer') as pres:
                pres.side_effect = lambda: setattr(acsv, 'resolved', MagicMock(
                ))
                iterable = acsv.writerows([1, 3])
                pres.assert_called_with()

    def test_csv_headers(self):
        "Generate namedtuples from headers."
        self.tcsv.truncate()
        self.tcsv << 'frist,last\n'
        self.tcsv << 'a,b'
        with self.tcsv.csv(header=True) as acsv:
            row = acsv.next()
            self.assertEqual('a', row.frist)
            self.assertEqual('b', row.last)

    def test_csv_headers_lower(self):
        "Generate namedtuples from headers."
        self.tcsv.truncate()
        self.tcsv << 'FRIST,LAST\n'
        self.tcsv << 'a,b'
        with self.tcsv.csv(header=True) as acsv:
            row = acsv.next()
            self.assertEqual('a', row.frist)
            self.assertEqual('b', row.last)

    def test_csv_headers_strip(self):
        "Generate namedtuples from headers."
        self.tcsv.truncate()
        self.tcsv << 'frist      ,     last\n'
        self.tcsv << 'a,b'
        with self.tcsv.csv(header=True) as acsv:
            row = acsv.next()
            self.assertEqual('a', row.frist)
            self.assertEqual('b', row.last)

    def test_csv_headers_whitespace(self):
        "Generate namedtuples from headers."
        self.tcsv.truncate()
        self.tcsv << 'frist thing      ,     last one\n'
        self.tcsv << 'a,b'
        with self.tcsv.csv(header=True) as acsv:
            row = acsv.next()
            self.assertEqual('a', row.frist_thing)
            self.assertEqual('b', row.last_one)

    def test_csv_headers_trailing_commas(self):
        "Generate namedtuples from headers."
        self.tcsv.truncate()
        self.tcsv << 'frist thing      ,     last one,\n'
        self.tcsv << 'a,b,'
        with self.tcsv.csv(header=True) as acsv:
            row = acsv.next()
            self.assertEqual('a', row.frist_thing)
            self.assertEqual('b', row.last_one)
            self.assertEqual('', row.field_2)

    def test_csv_headers_periods(self):
        "Generate namedtuples from headers."
        self.tcsv.truncate()
        self.tcsv << 'frist.thing,last.one\n'
        self.tcsv << 'a,b'
        with self.tcsv.csv(header=True) as acsv:
            row = acsv.next()
            self.assertEqual('a', row.frist_thing)
            self.assertEqual('b', row.last_one)
Example #31
0
 def test_ln_dest_exists(self):
     "Raise if dest exists"
     dest = Path(self.tdir) + '/hardlink'
     dest.touch()
     with self.assertRaises(exceptions.ExistsError):
         nix.ln(self.src, dest)
Example #32
0
 def test_ln_dest_exists(self):
     "Raise if dest exists"
     dest = Path(self.tdir) + '/hardlink'
     dest.touch()
     with self.assertRaises(exceptions.ExistsError):
         nix.ln(self.src, dest)
Example #33
0
 def test_ospathjoin_immutability(self):
     "os.path.join on a path shouldn't change it."
     p = Path('/tmp')
     p2 = os.path.join(p, 'foo')
     self.assertEqual('/tmp', p)
     self.assertEqual('/tmp/foo', p2)
Example #34
0
 def setUp(self):
     self.tdir = tempfile.mkdtemp()
     p = Path(self.tdir)
     nix.touch(p + 'foo.txt')
     nix.touch(p + 'bar.txt')
Example #35
0
 def test_rstrip(self):
     "Rstrip should be available. (shutil.move)"
     p = Path('/tmp/foo/bar/')
     bn = shutil._basename(p)
     self.assertEqual('bar', bn)
Example #36
0
 def test_ls_path(self):
     "list files in dir"
     contents = nix.ls(Path(self.tdir))
     contents.sort()
     self.assertEqual(['bar.txt', 'foo.txt'], contents)
Example #37
0
 def test_os_path_split(self):
     "should split it"
     p = Path('/tmp/my.file')
     splat = os.path.split(p)
     self.assertEqual('/tmp', splat[0])
     self.assertEqual('my.file', splat[1])
Example #38
0
class CSVTestCase(unittest.TestCase):
    def setUp(self):
        self.tfile = tempfile.mktemp()
        self.tcsv = Path(self.tfile)
        self.tcsv << '1,2,3,4'

    def test_repr(self):
        with self.tcsv.csv() as acsv:
            rep = '<Unresolved CSV {0}>'.format(self.tfile)
            self.assertEqual(rep, acsv.__repr__())

    def test_resolve_reader(self):
        "Resolve to a reader"
        with self.tcsv.csv() as acsv:
            self.assertIsInstance(acsv, formats.CSV)
            self.assertEqual(None, acsv.resolved)
            self.assertEqual(None, acsv.fh)
            iterable = acsv._resolve_reader()
            self.assertIsInstance(acsv.resolved, ReaderType)
            self.assertIsInstance(acsv.fh, file)
            self.assertEqual('rU', acsv.fh.mode)

    def test_reader_delimiter(self):
        "Should pass through"
        with self.tcsv.csv(delimiter='|') as acsv:
            with patch('csv.reader') as pread:
                acsv._resolve_reader()
                pread.assert_called_with(acsv.fh, delimiter='|')

    def test_resolve_writer(self):
        "Resolve to a writer"
        with self.tcsv.csv() as acsv:
            self.assertIsInstance(acsv, formats.CSV)
            self.assertEqual(None, acsv.resolved)
            self.assertEqual(None, acsv.fh)
            iterable = acsv._resolve_writer()
            self.assertIsInstance(acsv.resolved, WriterType)
            self.assertIsInstance(acsv.fh, file)
            self.assertEqual('w', acsv.fh.mode)

    def test_writer_delimiter(self):
        "Should pass through"
        with self.tcsv.csv(delimiter='|') as acsv:
            with patch('csv.writer') as pread:
                acsv._resolve_writer()
                pread.assert_called_with(acsv.fh, delimiter='|')

    def test_iter(self):
        "Iterate through rows"
        with self.tcsv.csv() as acsv:
            for i, row in enumerate(acsv):
                self.assertEqual(0, i)
                self.assertEqual(row, '1 2 3 4'.split())

    def test_iter_resolves(self):
        "Iterating should make us a reader"
        with self.tcsv.csv() as acsv:
            with patch.object(acsv, '_resolve_reader') as pres:
                iterable = acsv.__iter__()
                pres.assert_called_with()

    def test_iter_raises(self):
        "If we've resolved to a writer, raise"
        with self.tcsv.csv() as acsv:
            acsv._resolve_writer()
            with self.assertRaises(TypeError):
                acsv.__iter__()

    def test_next(self):
        "Next on the generator-like reader"
        with self.tcsv.csv() as acsv:
            self.assertEqual(acsv.next(), '1 2 3 4'.split())

    def test_next_resolves(self):
        "Nextating should make us a reader"
        with self.tcsv.csv() as acsv:
            with patch.object(acsv, '_resolve_reader') as pres:
                pres.side_effect = lambda: setattr(acsv, 'resolved', MagicMock())
                nxt = acsv.next()
                pres.assert_called_with()

    def test_next_raises(self):
        "If we've resolved to a wrnext, raise"
        with self.tcsv.csv() as acsv:
            acsv._resolve_writer()
            with self.assertRaises(AttributeError):
                acsv.next()

    def test_line_num_resolves(self):
        "Line num should resolve"
        with self.tcsv.csv() as acsv:
            with patch.object(acsv, '_resolve_reader') as pres:
                pres.side_effect = lambda: setattr(acsv, 'resolved', MagicMock())
                n = acsv.line_num
                pres.assert_called_with()

    def test_line_num_passes_through(self):
        "Line num should pass through"
        with self.tcsv.csv() as acsv:
            with patch('csv.reader') as pread:
                pread.return_value.line_num = 576
                n = acsv.line_num
                self.assertEqual(576, n)

    def test_line_num_raises(self):
        "If we're resolved to a writer, raise"
        with self.tcsv.csv() as acsv:
            acsv._resolve_writer()
            with self.assertRaises(AttributeError):
                n = acsv.line_num

    def test_writerow(self):
        "Write a row"
        with self.tcsv.csv() as acsv:
            acsv.writerow([1, 2, 3, 4])
        self.assertEqual('1,2,3,4\r\n', self.tcsv.contents)

    def test_writerow_resolves(self):
        "Iterating should make us a reader"
        with self.tcsv.csv() as acsv:
            with patch.object(acsv, '_resolve_writer') as pres:
                pres.side_effect = lambda : setattr(acsv, 'resolved', MagicMock())
                iterable = acsv.writerow([1, 3])
                pres.assert_called_with()

    def test_writerow_raises(self):
        "If we're resolved to a reader, raise"
        with self.tcsv.csv() as acsv:
            acsv._resolve_reader()
            with self.assertRaises(AttributeError):
                acsv.writerow([1, 2])

    def test_writerows_raises(self):
        "If we're resolved to a reader, raise"
        with self.tcsv.csv() as acsv:
            acsv._resolve_reader()
            with self.assertRaises(AttributeError):
                acsv.writerows([1, 2])

    def test_writerows(self):
        "Write a row"
        with self.tcsv.csv() as acsv:
            acsv.writerows([[1, 2], [3, 4]])
        self.assertEqual('1,2\r\n3,4\r\n', self.tcsv.contents)

    def test_writerows_resolves(self):
        "Iterating should make us a reader"
        with self.tcsv.csv() as acsv:
            with patch.object(acsv, '_resolve_writer') as pres:
                pres.side_effect = lambda : setattr(acsv, 'resolved', MagicMock())
                iterable = acsv.writerows([1, 3])
                pres.assert_called_with()

    def test_csv_headers(self):
        "Generate namedtuples from headers."
        self.tcsv.truncate()
        self.tcsv << 'frist,last\n'
        self.tcsv << 'a,b'
        with self.tcsv.csv(header=True) as acsv:
            row = acsv.next()
            self.assertEqual('a', row.frist)
            self.assertEqual('b', row.last)

    def test_csv_headers_lower(self):
        "Generate namedtuples from headers."
        self.tcsv.truncate()
        self.tcsv << 'FRIST,LAST\n'
        self.tcsv << 'a,b'
        with self.tcsv.csv(header=True) as acsv:
            row = acsv.next()
            self.assertEqual('a', row.frist)
            self.assertEqual('b', row.last)

    def test_csv_headers_strip(self):
        "Generate namedtuples from headers."
        self.tcsv.truncate()
        self.tcsv << 'frist      ,     last\n'
        self.tcsv << 'a,b'
        with self.tcsv.csv(header=True) as acsv:
            row = acsv.next()
            self.assertEqual('a', row.frist)
            self.assertEqual('b', row.last)

    def test_csv_headers_whitespace(self):
        "Generate namedtuples from headers."
        self.tcsv.truncate()
        self.tcsv << 'frist thing      ,     last one\n'
        self.tcsv << 'a,b'
        with self.tcsv.csv(header=True) as acsv:
            row = acsv.next()
            self.assertEqual('a', row.frist_thing)
            self.assertEqual('b', row.last_one)

    def test_csv_headers_trailing_commas(self):
        "Generate namedtuples from headers."
        self.tcsv.truncate()
        self.tcsv << 'frist thing      ,     last one,\n'
        self.tcsv << 'a,b,'
        with self.tcsv.csv(header=True) as acsv:
            row = acsv.next()
            self.assertEqual('a', row.frist_thing)
            self.assertEqual('b', row.last_one)
            self.assertEqual('', row.field_2)

    def test_csv_headers_periods(self):
        "Generate namedtuples from headers."
        self.tcsv.truncate()
        self.tcsv << 'frist.thing,last.one\n'
        self.tcsv << 'a,b'
        with self.tcsv.csv(header=True) as acsv:
            row = acsv.next()
            self.assertEqual('a', row.frist_thing)
            self.assertEqual('b', row.last_one)