import synapseclient
import pandas as pd
import mock
from nose.tools import assert_raises, assert_equals
import genie

class test_update_database:
	
	def setup(self):
		self.databasedf = pd.DataFrame({'UNIQUE_KEY':['test1','test2','test3'],
							  "test":['test1','test2','test3'],
							  "foo":[1,2,3],
							  "baz":[float('nan'),float('nan'),float('nan')]})
		self.databasedf.index = ['1_3','2_3','3_5']
	
	def test_append_rows_to_database(self):

		new_datadf = pd.DataFrame({'UNIQUE_KEY':['test1','test2','test3','test4'],
							  "test":['test1','test2','test3','test4'],
							  "foo":[1,2,3,4],
							  "baz":[float('nan'),float('nan'),float('nan'),3.2]})
		expecteddf = pd.DataFrame({'test':['test4'],
										  'foo':[4],
										  'baz':[3.2]})
		append_rows = genie.process_functions._append_rows(new_datadf, self.databasedf, 'UNIQUE_KEY')
		append_rows.fillna('',inplace=True)
		expecteddf.fillna('',inplace=True)
		assert append_rows.equals(expecteddf[append_rows.columns])

	def test_append_no_rows(self):
		append_rows = genie.process_functions._append_rows(self.databasedf, self.databasedf, 'UNIQUE_KEY')
		assert append_rows.empty

	def test_update_rows_to_database(self):
		new_datadf = pd.DataFrame({'UNIQUE_KEY':['test1','test2','test3'],
							  "test":['test','test2','test3'],
							  "foo":[1,3,3],
							  "baz":[float('nan'),5,float('nan')]})

		expecteddf = pd.DataFrame({"test":['test','test2'],
							  "foo":[1,3],
							  "baz":['',5],
							  'ROW_ID':['1','2'],
							  'ROW_VERSION':['3','3']})
		update_rows = genie.process_functions._update_rows(new_datadf, self.databasedf, 'UNIQUE_KEY')
		assert update_rows.equals(expecteddf[update_rows.columns])

	def test_update_rows_to_database_maintaintype(self):
		new_datadf = pd.DataFrame({'UNIQUE_KEY':['test1','test2','test3'],
							  "test":['test1','test2','test3'],
							  "foo":[1,3,3],
							  "baz":[float('nan'),5,float('nan')]})
		#Test that the datatype passed into from new_datadf gets preserved
		expecteddf = pd.DataFrame({"test":['test2'],
							  "foo":[3],
							  "baz":[5],
							  'ROW_ID':['2'],
							  'ROW_VERSION':['3']})
		expecteddf = expecteddf.astype({'baz':object}) 
		update_rows = genie.process_functions._update_rows(new_datadf, self.databasedf, 'UNIQUE_KEY')
		assert update_rows.equals(expecteddf[update_rows.columns])

	def test_update_empty_database(self):
		new_datadf = pd.DataFrame({'UNIQUE_KEY':['test4'],
									  "test":['test'],
									  "foo":[1],
									  "baz":[float('nan')]})
		update_rows = genie.process_functions._update_rows(new_datadf, self.databasedf, 'UNIQUE_KEY')
		assert update_rows.empty

	def test_update_no_rows(self):
		update_rows = genie.process_functions._update_rows(self.databasedf, self.databasedf, 'UNIQUE_KEY')
		assert update_rows.empty

	def test_delete_rows_to_database(self):
		new_datadf = pd.DataFrame({'UNIQUE_KEY':['test1'],
							  "test":['test1'],
							  "foo":[1],
							  "baz":[float('nan')]})
		expecteddf = pd.DataFrame({0:['2','3'],
							  	   1:['3','5']})
		delete_rows = genie.process_functions._delete_rows(new_datadf, self.databasedf, 'UNIQUE_KEY')
		assert delete_rows.equals(expecteddf)

	def test_delete_no_rows(self):
		delete_rows = genie.process_functions._delete_rows(self.databasedf, self.databasedf, 'UNIQUE_KEY')
		assert delete_rows.empty


@@ -407,16 +407,17 @@
 3_5'%5D%0A%09%0A
+%0A
 %09def tes
@@ -422,31 +422,468 @@
 est_
-append_rows_to_database
+_get_left_diff_df(self):%0A%09%09new_datadf = pd.DataFrame(%7B'UNIQUE_KEY':%5B'test1','test2','test3','test4'%5D,%0A%09%09%09%09%09%09%09  %22test%22:%5B'test1','test2','test3','test4'%5D,%0A%09%09%09%09%09%09%09  %22foo%22:%5B1,2,3,4%5D,%0A%09%09%09%09%09%09%09  %22baz%22:%5Bfloat('nan'),float('nan'),float('nan'),3.2%5D%7D)%0A%09%09get_diff = genie.process_functions._get_left_diff_df(new_datadf, self.databasedf, 'UNIQUE_KEY')%0A%09%09expecteddf = new_datadf.loc%5B%5B3%5D%5D%0A%09%09assert get_diff.equals(expecteddf%5Bget_diff.columns%5D)%0A%0A%0A%09def test_append__append_rows
 (sel
@@ -1446,18 +1446,23 @@
 est_
+norows__
 append_
-no_
 rows
@@ -1590,32 +1590,33 @@
 end_rows.empty%0A%0A
+%0A
 %09def test_update
@@ -1616,32 +1616,28 @@
 _update_
-rows_to_database
+_update_rows
 (self):%0A
@@ -2154,44 +2154,33 @@
 est_
-update_rows_to_database_maintaintype
+maintaintype__update_rows
 (sel
@@ -2800,29 +2800,29 @@
 est_
+no
 update_
-empty_database
+_update_rows
 (sel
@@ -3100,18 +3100,23 @@
 est_
+norows__
 update_
-no_
 rows
@@ -3273,24 +3273,20 @@
 ete_
-rows_to_database
+_delete_rows
 (sel
@@ -3641,18 +3641,23 @@
 est_
+norows__
 delete_
-no_
 rows

Add to unit tests for update database