#########################################################################
#
# Date: Jul 2004  Author: Daniel Stoffler
#
#       stoffler@scripps.edu
#
#       The Scripps Research Institute (TSRI)
#       Molecular Graphics Lab
#       La Jolla, CA 92037, USA
#
# Copyright: Daniel Stoffler, and TSRI
#   
# revision: Guillaume Vareille
#  
#########################################################################
#
# $Header: /opt/cvs/python/packages/share1.5/Vision/Tests/test_saveLoadSourceCode.py,v 1.4 2013/08/21 21:10:54 sanner Exp $
#
# $Id: test_saveLoadSourceCode.py,v 1.4 2013/08/21 21:10:54 sanner Exp $
#

import sys, os
from time import sleep

from NetworkEditor.net import Network
from NetworkEditor.simpleNE import NetworkNode
from Vision.VPE import VisualProgramingEnvironment
from Vision.StandardNodes import DialNE
from Vision.StandardNodes import stdlib

ed = None

###############################
## implement setUp and tearDown
###############################

def setUp():
    global ed
    ed = VisualProgramingEnvironment("test save and import source",
                                      withShell=0,
                                      visibleWidth=400, visibleHeight=300)
    ed.addLibraryInstance(stdlib, 'Vision.StandardNodes', 'stdlib')
    ed.master.update()
    ed.configure(withThreads=0)


def tearDown():
    ed.exit_cb()
    import gc
    gc.collect()

##########################
## Helper methods
##########################

def pause(sleepTime=0.1):
    ed.master.update()
    sleep(sleepTime)


############################################################################
## Tests
############################################################################


def test_01_saveImportDialUnchanged():
    # Test if we can save the source code of a dial node, import from this
    # saved source code, add the node to the network and compare to original
    net = ed.currentNetwork
    node1 = DialNE(library=stdlib)
    net.addNode(node1, 18, 20)
    # make sure there is no such file
    os.system("rm -f tmpSourceDial.py")
    os.system("rm -f tmpSourceDial.pyc")
    # save the source code of this node
    filename = 'tmpSourceDial.py'
    classname = 'TestDial' 
    node1.saveSource(filename, classname)
    pause()
    # import from the file
    from tmpSourceDial import TestDial
    node2 = TestDial()
    net.addNode(node2, 122, 20)
    pause()
    assert len(ed.currentNetwork.nodes) == 2,\
           "Expected 2, got %s"%len(ed.currentNetwork.nodes)
    assert classname == node2.name,\
           "classname: %s, node2.name: %s"%(classname, node2.name)
    assert node1.inNodeWidgetsVisibleByDefault == \
           node2.inNodeWidgetsVisibleByDefault,\
           "node1: %s, node2: %s"%(node1.inNodeWidgetsVisibleByDefault,
                                   node2.inNodeWidgetsVisibleByDefault)
    assert len(node1.inputPorts) == len(node2.inputPorts),\
           "ip node1: %s, ip node2: %s"%(
        len(node1.inputPorts), len(node2.inputPorts) )
    assert len(node1.outputPorts) == len(node2.outputPorts),\
        "op node1: %s, op node2: %s"%(
        len(node1.outputPorts), len(node2.outputPorts) )
    val1 = node1.inputPorts[0].widget.get()
    val2 = node2.inputPorts[0].widget.get()
    assert  val1 == val2, "val1: %s, val2: %s"%(val1, val2)
    # we clean up after us...
    os.system("rm -f tmpSourceDial.py")
    os.system("rm -f tmpSourceDial.pyc")


def test_02_saveImportDialNewName():
    # Test if we can save the source code of a dial node, import from this
    # saved source code, add the node to the network and compare to original
    # here, we change the node name
    net = ed.currentNetwork
    node1 = DialNE(library=stdlib)
    net.addNode(node1, 18, 20)
    # change node name
    node1.configure(name="New Test Dial")
    assert node1.name == "New Test Dial",\
           "Expected 'New Test Dial', got '%s'"%node1.name
    # make sure there is no such file
    os.system("rm -f tmpSourceDial2.py")
    os.system("rm -f tmpSourceDial2.pyc")
    # save the source code of this node
    node1.saveSource('tmpSourceDial2.py', 'TestDialNode')
    pause()
    # import from the file
    from tmpSourceDial2 import TestDialNode
    node2 = TestDialNode()
    net.addNode(node2, 122, 20)
    # we clean up after us...
    os.system("rm -f tmpSourceDial2.py")
    os.system("rm -f tmpSourceDial2.pyc")
    assert len(ed.currentNetwork.nodes) == 2,\
           "Expected 2, got %s"%len(ed.currentNetwork.nodes)
    assert 'TestDialNode' == node2.name,\
           "classname: %s, node2: %s"%('TestDialNode', node2.name)
    assert len(node1.inputPorts) == len(node2.inputPorts),\
           "ip node1: %s, ip node2: %s"%(
        len(node1.inputPorts), len(node2.inputPorts) )
    assert len(node1.outputPorts) == len(node2.outputPorts),\
           "op node1: %s, op node2: %s"%(
        len(node1.outputPorts), len(node2.outputPorts) )   
    val1 = node1.inputPorts[0].widget.get()
    val2 = node2.inputPorts[0].widget.get()
    assert  val1 == val2, "val1: %s, val2: %s"%(val1, val2)


def test_03_saveImportDialUnbindRebindWidget():
    # Test if we can save the source code of a dial node with the widget
    # unbound
    net = ed.currentNetwork
    node1 = DialNE(library=stdlib)
    net.addNode(node1, 18, 20)
    # unbind widget
    node1.inputPorts[0].unbindWidget()
    assert node1.inputPorts[0].widget is None,\
           "Expected None, got %s"%node1.inputPorts[0].widget
    # make sure there is no such file
    os.system("rm -f tmpSourceDial3.py")
    os.system("rm -f tmpSourceDial3.pyc")
    # save the source code of this node
    node1.saveSource('tmpSourceDial3.py', 'TestDialNode')
    pause()
    # import from the file
    from tmpSourceDial3 import TestDialNode
    node2 = TestDialNode()
    net.addNode(node2, 122, 20)
    # we clean up after us...
    os.system("rm -f tmpSourceDial3.py")
    os.system("rm -f tmpSourceDial3.pyc")
    assert node1.inputPorts[0].widget is None,\
           "Expected None, got %s"%node1.inputPorts[0].widget 
    # now rebind widget
    node1.inputPorts[0].rebindWidget()
    assert node1.inputPorts[0].widget is not None,\
           "Expected a widget, got %s"%node1.inputPorts[0].widget


def test_04_saveImportDialMacro():
    # test if we can save the source code of a macro and re-import
    net = ed.currentNetwork
    ## Creating a simple Dial Macro ##
    from NetworkEditor.macros import MacroNode
    node0 = MacroNode(name='macro0')
    net.addNode(node0, 18, 20)
    from Vision.StandardNodes import DialNE
    node3 = DialNE(constrkw = {}, name='Dial', library=stdlib)
    node0.macroNetwork.addNode(node3,93,100)
    ## saving connections for network macro0 ##
    node2 = node0.macroNetwork.opNode
    if node3 is not None and node2 is not None:
        node0.macroNetwork.connectNodes(
            node3, node2, "value", "new", blocking=True)
    node0.shrink()
    # make sure there is no such file
    os.system("rm -f tmpSourceDial4.py")
    os.system("rm -f tmpSourceDial4.pyc")
    # save the source code of this node
    node0.saveSource("tmpSourceDial4.py", 'TestDialMacroNew')
    pause()
    # import from the file
    from tmpSourceDial4 import TestDialMacroNew
    node2 = TestDialMacroNew()
    net.addNode(node2, 122, 20)
    # we clean up after us...
    os.system("rm -f tmpSourceDial4.py")
    os.system("rm -f tmpSourceDial4.pyc")
    pause()

## FIXME: test_05 will fail because the node does not come from a
## node library! We might want to support importing nodes from files, not
## libraries in the future

## def test_05_saveImportDialMacroThenSaveLoad():
##     # test if we can save the source code of a macro and re-import
##     # then save the network (not source) and reload
##     net = ed.currentNetwork
##     ## Creating a simple Dial Macro ##
##     from NetworkEditor.macros import MacroNode
##     node0 = MacroNode(name='macro0')
##     net.addNode(node0, 18, 20)
##     from Vision.StandardNodes import DialNE
##     from Vision.StandardNodes import stdlib
##     node3 = DialNE(constrkw = {}, name='Dial', library=stdlib)
##     node0.macroNetwork.addNode(node3,93,100)
##     ## saving connections for network macro0 ##
##     node2 = node0.macroNetwork.opNode
##     if node3 is not None and node2 is not None:
##         node0.macroNetwork.connectNodes(
##             node3, node2, "value", "new", blocking=True)
##     node0.shrink()
##     # make sure there is no such file
##     os.system("rm -f tmpSourceDial5.py")
##     os.system("rm -f tmpSourceDial5.pyc")
##     # save the source code of this node
##     node0.saveSource("tmpSourceDial5.py", 'TestDialMacroNew')
##     pause()
##     # delete the first macro
##     ed.currentNetwork.deleteNodes([node0])
##     # import from the file
##     from tmpSourceDial5 import TestDialMacroNew
##     node2 = TestDialMacroNew()
##     net.addNode(node2, 122, 20)
##     # we clean up after us...
##     os.system("rm -f tmpSourceDial5.py")
##     os.system("rm -f tmpSourceDial5.pyc")
##     pause()
##     # now save the network
##     ed.saveNetwork('tmpDial5_net.py')
##     # and delete the network
##     ed.deleteNetwork(ed.currentNetwork)
##     # load the file
##     ed.loadNetwork('tmpDial5_net.py')
##     # 1 macro node
##     assert len(ed.currentNetwork.nodes) == 1
##     macro = ed.currentNetwork.nodes[0]
##     # ip, op, Dial in macro network
##     assert len(macro.macroNetwork.nodes) == 3
##     # 3rd node must be dial
##     dial =  macro.macroNetwork.nodes[3]
##     assert dial.name == 'Dial'
##     # we clean up after us...
##     os.system("rm -f tmpDial5_net.py")




