#!/usr/bin/env python3

"""
This is the unittest script for CSV.py.
"""

import CSV as csv
import io,unittest
from collections import namedtuple
from pprint import pprint

class TestDialects(unittest.TestCase):

  def testListDialects(self):
    dlist=csv.list_dialects()
    self.assertTrue('excel' in dlist)
    self.assertTrue('excel-tab' in dlist)
    self.assertTrue('unix' in dlist)

  def testGetDialect(self):
    d=csv.get_dialect('excel')
    with self.assertRaises(csv.Error,msg="unknown dialect: 'x'"):
      csv.get_dialect('x')

  def testExcel(self):
    d=csv.get_dialect('excel')
    self.assertEqual(d.delimiter,',')
    self.assertEqual(d.quotechar,'"')
    self.assertEqual(d.lineterminator,'\r\n')
    self.assertEqual(d.quoting,csv.QUOTE_MINIMAL)
    self.assertEqual(d.doublequote,True)
    self.assertEqual(d.escapechar,None)
    self.assertEqual(d.skipinitialspace,False)
    self.assertEqual(d.strict,False)

  def testRegisterDialect(self):
    # SEP[Q[END[QSTYLE[DQUOTE[ESC[SKIPWS[STRICT]]]]]]]
    csv.register_dialect('escapable',escapechar='\\')
    d=csv.get_dialect('escapable')
    self.assertEqual(d.delimiter,',')
    self.assertEqual(d.quotechar,'"')
    self.assertEqual(d.quoting,csv.QUOTE_MINIMAL)
    self.assertEqual(d.lineterminator,'\r\n')
    self.assertEqual(d.doublequote,True)
    self.assertEqual(d.escapechar,'\\')
    self.assertEqual(d.skipinitialspace,False)
    self.assertEqual(d.strict,False)

  def testGTED(self):
    # SEP[Q[END[QSTYLE[DQUOTE[ESC[SKIPWS[STRICT]]]]]]]
    d=csv.parse_dialect('gted','|"LnfNff')
    self.assertEqual(d.delimiter,'|')
    self.assertEqual(d.quotechar,'"')
    self.assertEqual(d.quoting,csv.QUOTE_NONE)
    self.assertEqual(d.lineterminator,'\n')
    self.assertEqual(d.doublequote,False)
    self.assertEqual(d.escapechar,None)
    self.assertEqual(d.skipinitialspace,False)
    self.assertEqual(d.strict,False)

class Test1(unittest.TestCase):

  # Some simple CSV data in the "excel" dialect.
  excel_input1="""\
h1,h2,h3,h4,h5\r
a,b,c,d,e\r
f,g,h,i,j\r
k,l,m,n,o\r
p,q,r,w,t\r
u,v,w,x,y\r\n"""

  excel_input2="""\
first,last,saying\r
Jeff,Clough,"Uh ... Is this thing on?"\r
Cindy,Clough,"I've got to move-it, move-it!"\r
Ben,Franklin,"A penny saved is a penny earned."\r
Sam,Clemmons,Always do right. This will gratify some people and astonish the rest."""

  gted_input="""\
123456789|Clough|Jeff|jclough
234567891|Burdell|George P.|gburdell8
345678912|Flubendorf|Frida|fflubendorf3"""

  GtedData=namedtuple('GtedData','gtid lname fname uid')

  def testReader1(self):
    # Read our data into a list of rows.
    input=io.StringIO(self.excel_input1)
    reader=csv.reader(input,'excel')
    data=[row for row in reader]
    # Write these rows to a string.
    output=io.StringIO()
    writer=csv.writer(output,'excel')
    writer.writerows(data)
    # Compare the input data to the output string.
    self.assertEqual(input.getvalue(),output.getvalue())

  def testReader2(self):
    # Read some data.
    input=io.StringIO(self.excel_input2)
    reader=csv.DictReader(input)
    data=[type('',(),d) for d in reader]
    saying={f"{d.first} {d.last}":d.saying for d in data}
    # Test some data.
    self.assertEqual(saying['Jeff Clough'],'Uh ... Is this thing on?')
    self.assertEqual(saying['Ben Franklin'],'A penny saved is a penny earned.')

  def testGtedData(self):
    # Read some data.
    gted=csv.parse_dialect('gted','|"LnfNff')
    data=[self.GtedData(*row) for row in csv.reader(io.StringIO(self.gted_input),dialect=gted)]
    # Convert list data to dictionary (for easier testing).
    data={r.uid:r for r in data}
    # Check what we've read.
    self.assertEqual(data['jclough'].gtid,'123456789')
    self.assertEqual(data['gburdell8'].fname,'George P.')
    self.assertEqual(data['fflubendorf3'].lname,'Flubendorf')

if __name__=='__main__':
  unittest.main()
