#!/usr/bin/env python
#  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
#
#  Use of this source code is governed by a BSD-style license
#  that can be found in the LICENSE file in the root of the source
#  tree. An additional intellectual property rights grant can be found
#  in the file PATENTS.  All contributing project authors may
#  be found in the AUTHORS file in the root of the source tree.

__author__ = 'kjellander@webrtc.org (Henrik Kjellander)'

import unittest
import webrtc.data_helper

class Test(unittest.TestCase):

  def setUp(self):
    # Simulate frame data from two different test runs, with 2 frames each.
    self.frame_data_0 = [{'frame_number': 0, 'ssim': 0.5, 'psnr': 30.5}, 
                         {'frame_number': 1, 'ssim': 0.55, 'psnr': 30.55}]
    self.frame_data_1 = [{'frame_number': 0, 'ssim': 0.6, 'psnr': 30.6},
                         {'frame_number': 0, 'ssim': 0.66, 'psnr': 30.66}]
    self.all_data = [ self.frame_data_0, self.frame_data_1 ]
    
    # Test with frame_number column in a non-first position sice we need to 
    # support reordering that to be able to use the gviz_api as we want.
    self.type_description = {
                             'ssim': ('number', 'SSIM'),
                             'frame_number': ('number', 'Frame number'),
                             'psnr': ('number', 'PSRN'),
    }
    self.names = ["Test 0", "Test 1"]
    self.configurations = [
     [{'name': 'name', 'value': 'Test 0'},
      {'name': 'test_number', 'value': '13'},
      {'name': 'input_filename', 'value': 'foreman_cif.yuv'},
     ],
     [{'name': 'name', 'value': 'Test 1'},
      {'name': 'test_number', 'value': '5'},
      {'name': 'input_filename', 'value': 'foreman_cif.yuv'},
     ],
    ]

  def testCreateData(self):
    messages = []
    helper = webrtc.data_helper.DataHelper(self.all_data, self.type_description,
                                           self.names, messages)
    description, data_table = helper.CreateData('ssim')
    self.assertEqual(3, len(description))
    self.assertTrue('frame_number' in description)
    self.assertTrue('ssim_0' in description)
    self.assertTrue('number' in description['ssim_0'][0])
    self.assertTrue('Test 0' in description['ssim_0'][1])
    self.assertTrue('ssim_1' in description)
    self.assertTrue('number' in description['ssim_1'][0])
    self.assertTrue('Test 1' in description['ssim_1'][1])

    self.assertEqual(0, len(messages))

    self.assertEquals(2, len(data_table))
    row = data_table[0]
    self.assertEquals(0, row['frame_number'])
    self.assertEquals(0.5, row['ssim_0'])
    self.assertEquals(0.6, row['ssim_1'])
    row = data_table[1]
    self.assertEquals(1, row['frame_number'])
    self.assertEquals(0.55, row['ssim_0'])
    self.assertEquals(0.66, row['ssim_1'])
    
    description, data_table = helper.CreateData('psnr') 
    self.assertEqual(3, len(description))
    self.assertTrue('frame_number' in description)
    self.assertTrue('psnr_0' in description)
    self.assertTrue('psnr_1' in description) 
    self.assertEqual(0, len(messages)) 

    self.assertEquals(2, len(data_table))
    row = data_table[0]
    self.assertEquals(0, row['frame_number'])
    self.assertEquals(30.5, row['psnr_0'])
    self.assertEquals(30.6, row['psnr_1'])
    row = data_table[1]
    self.assertEquals(1, row['frame_number'])
    self.assertEquals(30.55, row['psnr_0'])
    self.assertEquals(30.66, row['psnr_1'])
  
  def testGetOrdering(self):
    """ Tests that the ordering help method returns a list with frame_number 
       first and the rest sorted alphabetically """
    messages = []
    helper = webrtc.data_helper.DataHelper(self.all_data, self.type_description,
                                           self.names, messages)
    description, data_table = helper.CreateData('ssim')
    columns = helper.GetOrdering(description)
    self.assertEqual(3, len(columns))
    self.assertEqual(0, len(messages))
    self.assertEqual('frame_number', columns[0])
    self.assertEqual('ssim_0', columns[1])
    self.assertEqual('ssim_1', columns[2])
    
  def testCreateConfigurationTable(self):
    messages = []
    helper = webrtc.data_helper.DataHelper(self.all_data, self.type_description,
                                           self.names, messages)
    description, data = helper.CreateConfigurationTable(self.configurations)
    self.assertEqual(3, len(description))  # 3 columns
    self.assertEqual(2, len(data))  # 2 data sets
    self.assertTrue(description.has_key('name'))
    self.assertTrue(description.has_key('test_number'))
    self.assertTrue(description.has_key('input_filename'))
    self.assertEquals('Test 0', data[0]['name'])
    self.assertEquals('Test 1', data[1]['name'])
    
if __name__ == "__main__":
  unittest.main()
