#! /usr/bin/env python
# -*- coding: utf-8 -*-
'''
Copyright (C) 2012  Diego Torres Milano
Created on Feb 5, 2012

@author: diego
'''

import sys
import os
import time
import StringIO
import unittest
import exceptions
import platform

# PyDev sets PYTHONPATH, use it
try:
    for p in os.environ['PYTHONPATH'].split(':'):
        if not p in sys.path:
            sys.path.append(p)
except:
    pass

try:
    sys.path.insert(0, os.path.join(os.environ['ANDROID_VIEW_CLIENT_HOME'], 'src'))
except:
    pass

from com.dtmilano.android.viewclient import *
from mocks import MockDevice, MockViewServer
from mocks import DUMP, DUMP_SAMPLE_UI, VIEW_MAP, VIEW_MAP_API_8, VIEW_MAP_API_17, RUNNING, STOPPED, WINDOWS

os_name = platform.system()
if os_name.startswith('Linux'):
    TRUE = '/bin/true'
else:
    TRUE = '/usr/bin/true'

class ViewTest(unittest.TestCase):

    def setUp(self):
        self.view = View(VIEW_MAP, None, -1)

    def tearDown(self):
        try:
            del os.environ['ANDROID_SERIAL']
        except:
            pass

    def testViewFactory_View(self):
        attrs = {'class': 'android.widget.AnyView', 'text:mText': 'Button with ID'}
        view = View.factory(attrs, None, -1)
        self.assertTrue(isinstance(view, View))

    def testViewFactory_TextView(self):
        attrs = {'class': 'android.widget.TextView', 'text:mText': 'Button with ID'}
        view = View.factory(attrs, None, -1)
        self.assertTrue(isinstance(view, TextView))

    def testViewFactory_TextView(self):
        attrs = {'class': 'android.widget.EditText', 'text:mText': 'Button with ID'}
        view = View.factory(attrs, None, -1)
        self.assertTrue(isinstance(view, EditText))

    def testView_notSpecifiedSdkVersion(self):
        device = MockDevice()
        view = View(VIEW_MAP, device, -1)
        self.assertEqual(device.version, view.build[VERSION_SDK_PROPERTY])

    def testView_specifiedSdkVersion_8(self):
        view = View(VIEW_MAP_API_8, MockDevice(), 8)
        self.assertEqual(8, view.build[VERSION_SDK_PROPERTY])

    def testView_specifiedSdkVersion_10(self):
        view = View(VIEW_MAP, MockDevice(), 10)
        self.assertEqual(10, view.build[VERSION_SDK_PROPERTY])

    def testView_specifiedSdkVersion_16(self):
        view = View(VIEW_MAP, MockDevice(), 16)
        self.assertEqual(16, view.build[VERSION_SDK_PROPERTY])

    def testInnerMethod(self):
        v = View({'isChecked()':'true'}, None)
        self.assertTrue(v.isChecked())
        v.map['isChecked()'] = 'false'
        self.assertFalse(v.isChecked(), "Expected False but is %s {%s}" % (v.isChecked(), v.map['isChecked()']))
        self.assertFalse(v.isChecked())
        v.map['other'] = 1
        self.assertEqual(1, v.other())
        v.map['evenMore'] = "ABC"
        self.assertEqual("ABC", v.evenMore())
        v.map['more'] = "abc"
        v.map['more'] = v.evenMore()
        self.assertEqual("ABC", v.more())
        v.map['isMore()'] = 'true'
        self.assertTrue(v.isMore())

    def testGetClass(self):
        self.assertEqual('android.widget.ToggleButton', self.view.getClass())

    def testGetId(self):
        self.assertEqual('id/button_with_id', self.view.getId())

    def testTextPropertyForDifferentSdkVersions(self):
        VP = { -1:TEXT_PROPERTY, 8:TEXT_PROPERTY_API_10, 10:TEXT_PROPERTY_API_10, 15:TEXT_PROPERTY, 16:TEXT_PROPERTY_UI_AUTOMATOR, 17:TEXT_PROPERTY_UI_AUTOMATOR}
        for version, textProperty in VP.items():
            view = View(None, None, version)
            self.assertEqual(textProperty, view.textProperty, msg='version %d: expected: %s actual: %s' % (version, textProperty, view.textProperty))

    def testTextPropertyForDifferentSdkVersions_device(self):
        VP = { -1:TEXT_PROPERTY, 8:TEXT_PROPERTY_API_10, 10:TEXT_PROPERTY_API_10, 15:TEXT_PROPERTY, 16:TEXT_PROPERTY_UI_AUTOMATOR, 17:TEXT_PROPERTY_UI_AUTOMATOR}
        for version, textProperty in VP.items():
            device = MockDevice(version=version)
            view = View(None, device, -1)
            self.assertEqual(textProperty, view.textProperty, msg='version %d' % version)

    def testLeftPropertyForDifferentSdkVersions(self):
        VP = { -1:LEFT_PROPERTY, 8:LEFT_PROPERTY_API_8, 10:LEFT_PROPERTY, 15:LEFT_PROPERTY, 16:LEFT_PROPERTY, 17:LEFT_PROPERTY}
        for version, leftProperty in VP.items():
            view = View(None, None, version)
            self.assertEqual(leftProperty, view.leftProperty, msg='version %d' % version)

    def testLeftPropertyForDifferentSdkVersions_device(self):
        VP = { -1:LEFT_PROPERTY, 8:LEFT_PROPERTY_API_8, 10:LEFT_PROPERTY, 15:LEFT_PROPERTY, 16:LEFT_PROPERTY, 17:LEFT_PROPERTY}
        for version, leftProperty in VP.items():
            device = MockDevice(version=version)
            view = View(None, device, -1)
            self.assertEqual(leftProperty, view.leftProperty, msg='version %d' % version)

    def testTopPropertyForDifferentSdkVersions(self):
        VP = { -1:TOP_PROPERTY, 8:TOP_PROPERTY_API_8, 10:TOP_PROPERTY, 15:TOP_PROPERTY, 16:TOP_PROPERTY, 17:TOP_PROPERTY}
        for version, topProperty in VP.items():
            view = View(None, None, version)
            self.assertEqual(topProperty, view.topProperty, msg='version %d' % version)

    def testTopPropertyForDifferentSdkVersions_device(self):
        VP = { -1:TOP_PROPERTY, 8:TOP_PROPERTY_API_8, 10:TOP_PROPERTY, 15:TOP_PROPERTY, 16:TOP_PROPERTY, 17:TOP_PROPERTY}
        for version, topProperty in VP.items():
            device = MockDevice(version=version)
            view = View(None, device, -1)
            self.assertEqual(topProperty, view.topProperty, msg='version %d' % version)

    def testWidthPropertyForDifferentSdkVersions(self):
        VP = { -1:WIDTH_PROPERTY, 8:WIDTH_PROPERTY_API_8, 10:WIDTH_PROPERTY, 15:WIDTH_PROPERTY, 16:WIDTH_PROPERTY, 17:WIDTH_PROPERTY}
        for version, widthProperty in VP.items():
            view = View(None, None, version)
            self.assertEqual(widthProperty, view.widthProperty, msg='version %d' % version)

    def testWidthPropertyForDifferentSdkVersions_device(self):
        VP = { -1:WIDTH_PROPERTY, 8:WIDTH_PROPERTY_API_8, 10:WIDTH_PROPERTY, 15:WIDTH_PROPERTY, 16:WIDTH_PROPERTY, 17:WIDTH_PROPERTY}
        for version, widthProperty in VP.items():
            device = MockDevice(version=version)
            view = View(None, device, -1)
            self.assertEqual(widthProperty, view.widthProperty, msg='version %d' % version)

    def testHeightPropertyForDifferentSdkVersions(self):
        VP = { -1:HEIGHT_PROPERTY, 8:HEIGHT_PROPERTY_API_8, 10:HEIGHT_PROPERTY, 15:HEIGHT_PROPERTY, 16:HEIGHT_PROPERTY, 17:HEIGHT_PROPERTY}
        for version, heightProperty in VP.items():
            view = View(None, None, version)
            self.assertEqual(heightProperty, view.heightProperty, msg='version %d' % version)

    def testHeightPropertyForDifferentSdkVersions_device(self):
        VP = { -1:HEIGHT_PROPERTY, 8:HEIGHT_PROPERTY_API_8, 10:HEIGHT_PROPERTY, 15:HEIGHT_PROPERTY, 16:HEIGHT_PROPERTY, 17:HEIGHT_PROPERTY}
        for version, heightProperty in VP.items():
            device = MockDevice(version=version)
            view = View(None, device, -1)
            self.assertEqual(heightProperty, view.heightProperty, msg='version %d' % version)

    def testGetText(self):
        self.assertTrue(self.view.map.has_key('text:mText'))
        self.assertEqual('Button with ID', self.view.getText())
        self.assertEqual('Button with ID', self.view['text:mText'])

    def testGetX_specifiedSdkVersion_8(self):
        view = View(VIEW_MAP_API_8, MockDevice(), 8)
        self.assertEqual(8, view.build[VERSION_SDK_PROPERTY])
        self.assertEqual(50, view.getX())

    def testGetX_specifiedSdkVersion_10(self):
        view = View(VIEW_MAP, MockDevice(), 10)
        self.assertEqual(10, view.build[VERSION_SDK_PROPERTY])
        self.assertEqual(50, view.getX())

    def testGetY_specifiedSdkVersion_8(self):
        view = View(VIEW_MAP_API_8, MockDevice(), 8)
        self.assertEqual(8, view.build[VERSION_SDK_PROPERTY])
        self.assertEqual(316, view.getY())

    def testGetY_specifiedSdkVersion_10(self):
        view = View(VIEW_MAP, MockDevice(), 10)
        self.assertEqual(10, view.build[VERSION_SDK_PROPERTY])
        self.assertEqual(316, view.getY())

    def testGetWidth(self):
        self.assertEqual(1140, self.view.getWidth())

    def testGetHeight(self):
        self.assertEqual(48, self.view.getHeight())

    def testGetUniqueId(self):
        self.assertEqual('id/button_with_id', self.view.getUniqueId())

    def testGetUniqueIdEqualsToIdWhenIdIsSpecified(self):
        self.assertEqual(self.view.getId(), self.view.getUniqueId())

    def testName_Layout_mLeft(self):
        v = View({'layout:mLeft':200}, None)
        self.assertEqual(200, v.layout_mLeft())

    def testNameWithColon_this_is_a_fake_name(self):
        v = View({'this:is_a_fake_name':1}, None)
        self.assertEqual(1, v.this_is_a_fake_name())

    def testNameWith2Colons_this_is_another_fake_name(self):
        v = View({'this:is:another_fake_name':1}, None)
        self.assertEqual(1, v.this_is_another_fake_name())

    def testViewWithoutId(self):
        v = View({'mID':'id/NO_ID', 'text:mText':'Some text'}, None)
        self.assertEqual('id/NO_ID', v.getId())

    def testInexistentMethodName(self):
        v = View({'foo':1}, None)
        try:
            v.bar()
            raise Exception("AttributeError not raised")
        except AttributeError:
            pass

    def testViewTreeRoot(self):
        root = View({'root':1}, None)
        self.assertTrue(root.parent == None)

    def testViewTree(self):
        root = View({'root':1}, None)
        children = ["A", "B", "C"]
        for s in children:
            root.add(View({s:1}, None))

        self.assertEquals(len(children), len(root.children))

    def testViewTreeParent(self):
        root = View({'root':1}, None)
        children = ["A", "B", "C"]
        for s in children:
            root.add(View({s:1}, None))

        for ch in root.children:
            self.assertTrue(ch.parent == root)

    def testContainsPoint_api15(self):
        v = View(VIEW_MAP, MockDevice(), 15)
        (X, Y, W, H) = v.getPositionAndSize()
        self.assertEqual(X, v.getX())
        self.assertEqual(Y, v.getY())
        self.assertEqual(W, v.getWidth())
        self.assertEqual(H, v.getHeight())
        self.assertTrue(v.containsPoint((v.getCenter())))

    def testContainsPoint_api17(self):
        v = View(VIEW_MAP_API_17, MockDevice(), 17)
        (X, Y, W, H) = v.getPositionAndSize()
        self.assertEqual(X, v.getX())
        self.assertEqual(Y, v.getY())
        self.assertEqual(W, v.getWidth())
        self.assertEqual(H, v.getHeight())
        self.assertTrue(v.containsPoint((v.getCenter())))

    def testIsClickable_api15(self):
        v = View(VIEW_MAP, MockDevice(), 15)
        self.assertTrue(v.isClickable())

    def testIsClickable_api17(self):
        v = View(VIEW_MAP_API_17, MockDevice(), 17)
        self.assertTrue(v.isClickable())

class ViewClientTest(unittest.TestCase):

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def testInit_adb(self):
        device = MockDevice()
        vc = ViewClient(device, device.serialno, adb=TRUE, autodump=False)
        self.assertNotEqual(None, vc)

    def testInit_adbNone(self):
        # FIXME: there's a problem here when the mock device is created,
        # it's intended to be API=15, mock ViewServer is started and then
        # adb tries (unsuccessfuly) to forward the ports (expected because
        # adb does not know anything about mock devices).
        # Then
        #    error: device not found
        # appears in the console
        device = MockDevice()
        try:
            vc = ViewClient(device, device.serialno, adb=None, autodump=False)
            self.assertIsNotNone(vc)
        except subprocess.CalledProcessError:
            # This is needed because the ports cannot be forwarded if there is no device connected
            pass

    def testExceptionDeviceNotConnected(self):
        try:
            vc = ViewClient(None, None)
        except Exception, e:
            self.assertEqual('Device is not connected', e.message)

    def testConnectToDeviceOrExit_environ(self):
        sys.argv = ['']
        os.environ['ANDROID_SERIAL'] = 'ABC123'
        try:
            ViewClient.connectToDeviceOrExit(timeout=1, verbose=True)
        except RuntimeError, e:
            msg = str(e)
            if re.search('Is adb running on your computer?', msg):
                # This test required adb running
                self.fail(msg)
            elif re.search("There are no connected devices", msg):
                # special case, when there are no devices connected then the
                # serialno specified doesn't matter
                pass
            elif not re.search("couldn't find device that matches 'ABC123'", msg):
                self.fail(msg)
        except exceptions.SystemExit, e:
            self.assertEquals(3, e.code)
        except Exception, e: #FIXME: java.lang.NullPointerException:
            self.fail('Serialno was not taken from environment: ' + msg)

    def testConnectToDeviceOrExit_serialno(self):
        sys.argv = ['']
        try:
            ViewClient.connectToDeviceOrExit(timeout=1, verbose=True, serialno='ABC123')
        except RuntimeError, e:
            msg = str(e)
            if re.search('Is adb running on your computer?', msg):
                # This test required adb running
                self.fail(msg)
            elif re.search("There are no connected devices", msg):
                # special case, when there are no devices connected then the
                # serialno specified doesn't matter
                pass
            elif not re.search("couldn't find device that matches 'ABC123'", msg):
                self.fail(msg)
        except exceptions.SystemExit, e:
            self.assertEquals(3, e.code)
        except Exception, e: #FIXME: java.lang.NullPointerException:
            self.fail('Serialno was not taken from argument: ' + str(e))

    def testConstructor(self):
        device = MockDevice()
        vc = ViewClient(device, device.serialno, adb=TRUE, autodump=False)
        self.assertNotEquals(None, vc)

    def testMapSerialNo_noPortSpecified(self):
        vc = ViewClient(MockDevice(), serialno='192.168.1.100', adb=TRUE, autodump=False)
        self.assertEqual('192.168.1.100:5555', vc.serialno)

    def testMapSerialNo_portSpecified(self):
        vc = ViewClient(MockDevice(), serialno='192.168.1.100:5555', adb=TRUE, autodump=False)
        self.assertEqual('192.168.1.100:5555', vc.serialno)

    def testMapSerialNo_emulator(self):
        vc = ViewClient(MockDevice(), serialno='emulator-5556', adb=TRUE, autodump=False)
        self.assertEqual('emulator-5556', vc.serialno)

    def testMapSerialNo_regex(self):
        # This is an edge case. A regex should not be used as the serialno in ViewClient as it's
        # behavior is not well defined.
        # MonkeyRunner.waitForConnection() accepts a regexp as serialno but adb -s doesn't
        try:
            ViewClient(MockDevice(),  serialno='.*', adb=TRUE, autodump=False)
            self.fail()
        except ValueError:
            pass

    def testMapSerialNo_None(self):
        device = MockDevice()
        try:
            ViewClient(device, None, adb=TRUE, autodump=False)
            self.fail()
        except ValueError:
            pass

    def testGetProperty_displayWidth(self):
        device = MockDevice()
        self.assertEqual(768, device.getProperty('display.width'))

    def testGetProperty_displayHeight(self):
        device = MockDevice()
        self.assertEqual(1184, device.getProperty('display.height'))

    def __mockTree(self, dump=DUMP, version=15, language='en'):
        device = MockDevice(version=version, language=language)
        vc = ViewClient(device, serialno=device.serialno, adb=TRUE, autodump=False)
        self.assertNotEquals(None, vc)
        if version <= 15:
            # We don't want to invoke the ViewServer or MockViewServer for this
            vc.setViews(dump)
        else:
            vc.dump()
        return vc

    def __mockWindows(self, windows=WINDOWS):
        device = MockDevice()
        vc = ViewClient(device, serialno=device.serialno, adb=TRUE, autodump=False)
        self.assertNotEquals(None, vc)
        vc.windows = windows
        return vc

    def testRoot(self):
        vc = self.__mockTree()
        root = vc.root
        self.assertTrue(root != None)
        self.assertTrue(root.parent == None)
        self.assertTrue(root.getClass() == 'com.android.internal.policy.impl.PhoneWindow$DecorView')

    def testParseTree(self):
        vc = self.__mockTree()
        # eat all the output
        vc.traverse(vc.root, transform=self.__eatIt)
        # We know there are 23 views in ViewServer mock tree
        self.assertEqual(23, len(vc.getViewIds()))

    def testParsetree_api17(self):
        vc = self.__mockTree(version=17)
        # eat all the output
        vc.traverse(vc.root, transform=self.__eatIt)
        # We know there are 9 views in UiAutomator mock tree
        self.assertEqual(9, len(vc.getViewIds()))

    def testParsetree_api17_zh(self):
        vc = self.__mockTree(version=17, language='zh')
        # eat all the output
        vc.traverse(vc.root, transform=self.__eatIt)
        # We know there are 21 views in UiAutomator mock tree
        self.assertEqual(21, len(vc.getViewIds()))

    def __testViewByIds_apiIndependent(self, vc):
        viewsbyId = vc.getViewsById()
        self.assertNotEquals(None, viewsbyId)
        for k, v in viewsbyId.items():
            self.assertTrue(isinstance(k, str) or isinstance(k, unicode))
            self.assertTrue(isinstance(v, View), "v=" + unicode(v) + " is not a View")
            self.assertTrue(re.match("id/.*", v.getUniqueId()) != None)
            self.assertEquals(k, v.getUniqueId())

    def testGetViewsById(self):
        vc = self.__mockTree()
        self.__testViewByIds_apiIndependent(vc)

    def testGetViewsById_api17(self):
        vc = self.__mockTree(version=17)
        self.__testViewByIds_apiIndependent(vc)

    def testGetViewsById_api17_zh(self):
        vc = self.__mockTree(version=17, language='zh')
        self.__testViewByIds_apiIndependent(vc)

    def testNewViewClientInstancesDontDuplicateTree(self):
        vc = {}
        n = {}
        for i in range(10):
            vc[i] = self.__mockTree()
            n[i] = len(vc[i].getViewIds())

        for i in range(1, 10):
            self.assertEquals(n[0], n[i])

    def testTraverseShowClassIdAndText(self):
        device = MockDevice()
        root = View({'text:mText':'0', 'class': 'android.widget.View', 'mID': 0}, device)
        root.add(View({'text:mText':'1', 'class': 'android.widget.View', 'mID': 1}, device))
        root.add(View({'text:mText':'2', 'class': 'android.widget.View', 'mID': 2}, device))
        v3 = View({'text:mText':'3', 'class': 'android.widget.View', 'mID':3}, device)
        root.add(v3)
        v35 = View({'text:mText':'5', 'getTag()':'v35', 'class': 'android.widget.View', 'mID': 35}, device)
        v3.add(v35)
        vc = ViewClient(device, device.serialno, adb=TRUE, autodump=False)
        self.assertNotEquals(None, vc)
        treeStr = StringIO.StringIO()
        vc.traverse(root=root, transform=ViewClient.TRAVERSE_CIT, stream=treeStr)
        self.assertNotEquals(None, treeStr.getvalue())
        lines = treeStr.getvalue().splitlines()
        self.assertEqual(5, len(lines), "lines=%s" % lines)
        self.assertEqual('android.widget.View 0 0', lines[0])
        citRE = re.compile(' +android.widget.View \d+ \d+')
        for l in lines[1:]:
            self.assertTrue(citRE.match(l), 'l=%s' % l)


    def testTraverseShowClassIdTextAndCenter(self):
        device = MockDevice()
        root = View({'mID':'0', 'text:mText':'0', 'layout:mLeft':0, 'layout:mTop':0}, device)
        root.add(View({'mID':'1', 'text:mText':'1', 'layout:mLeft':1, 'layout:mTop':1}, device))
        root.add(View({'mID':'2', 'text:mText':'2', 'layout:mLeft':2, 'layout:mTop':2}, device))
        v3 = View({'mID':'3', 'text:mText':'3', 'layout:mLeft':3, 'layout:mTop':3}, device)
        root.add(v3)
        v35 = View({'mID':'5', 'text:mText':'5', 'getTag()':'v35', 'layout:mLeft':5, 'layout:mTop':5}, device)
        v3.add(v35)
        vc = ViewClient(device, device.serialno, adb=TRUE, autodump=False)
        self.assertNotEquals(None, vc)
        treeStr = StringIO.StringIO()
        vc.traverse(root=root, transform=ViewClient.TRAVERSE_CITC, stream=treeStr)
        self.assertNotEquals(None, treeStr.getvalue())
        lines = treeStr.getvalue().splitlines()
        self.assertEqual(5, len(lines))
        self.assertEqual('None 0 0 (0, 0)', lines[0])
        citRE = re.compile(' +None \d+ \d+ \(\d+, \d+\)')
        for l in lines[1:]:
            self.assertTrue(citRE.match(l))

    def __getClassAndId(self, view):
        try:
            return "%s %s %s %s" % (view.getClass(), view.getId(), view.getUniqueId(), view.getCoords())
        except Exception, e:
            return "Exception in view=%s: %s" % (view.__smallStr__(), e)

    def __eatIt(self, view):
        return ""

    def testViewWithNoIdReceivesUniqueId(self):
        vc = self.__mockTree()

        # We know there are 6 views without id in the mock tree
        for i in range(1, 6):
            self.assertNotEquals(None, vc.findViewById("id/no_id/%d" % i))

    def testTextWithSpaces(self):
        vc = self.__mockTree()
        self.assertNotEqual(None, vc.findViewWithText('Medium Text'))

    def testTextWithVeryLargeContent(self):
        TEXT = """\
MOCK@412a9d08 mID=7,id/test drawing:mForeground=4,null padding:mForegroundPaddingBottom=1,0 text:mText=319,[!   "   #   $   %   &   '   (   )   *   +   ,   -   .   /   0   1   2   3   4   5   6   7   8   9   :   ;   <   =   >   ?   @   A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P   Q   R   S   T   U   V   W   X   Y   Z   [   \   ]   ^   _   `   a   b   c   d   e   f   g   h   i   j   k   l   m   n   o   p] mViewFlags=11,-1744830336\
"""
        vc = self.__mockTree(TEXT)
        test = vc.findViewById('id/test')
        text = test.getText()
        self.assertEqual(319, len(text))
        self.assertEqual('[', text[0])
        self.assertEqual(']', text[318])
        self.assertEqual('-1744830336', test['mViewFlags'])

    def testActionBarSubtitleCoordinates(self):
        vc = self.__mockTree(dump=DUMP_SAMPLE_UI)
        toggleButton = vc.findViewById('id/button_with_id')
        self.assertNotEqual(None, toggleButton)
        textView3 = vc.findViewById('id/textView3')
        self.assertNotEqual(None, textView3)
        x = toggleButton.getX()
        y = toggleButton.getY()
        w = toggleButton.getWidth()
        h = toggleButton.getHeight()
        xy = toggleButton.getXY()
        coords = toggleButton.getCoords()
        self.assertNotEqual(None, textView3.getText())
        self.assertNotEqual("", textView3.getText().strip())
        lv = textView3.getText().strip().split()
        _list = [ eval(str(v)) for v in lv ]
        tx = _list[1][0]
        ty = _list[1][1]
        tsx = _list[1][0]
        tsy = _list[1][1]
        self.assertEqual(tx, x)
        self.assertEqual(ty, y)
        self.assertEqual((tsx, tsy), xy)
        self.assertEqual(((tsx, tsy), (xy[0] + w, xy[1] + h)), coords)

    def testServiceStoppedAfterDestructor(self):
        device = MockDevice()
        self.assertTrue(device.service == STOPPED)
        if True:
            vc = ViewClient(device, device.serialno, adb=TRUE, autodump=False)
            self.assertTrue(device.service == RUNNING)
            vc.__del__()
        # Perhpas there are other ViewClients using the same server, we cannot expect it stops
        #self.assertTrue(device.service == STOPPED)

    def testList(self):
        vc = self.__mockWindows()
        self.assertNotEqual(None, vc.windows)

    def testFindViewByIdOrRaise(self):
        vc = self.__mockTree(dump=DUMP_SAMPLE_UI)
        vc.findViewByIdOrRaise('id/up')

    def testFindViewByIdOrRaise_api17(self):
        vc = self.__mockTree(version=17)
        vc.traverse(stream=self.openDevNull())
        vc.findViewByIdOrRaise('id/no_id/9')

    def testFindViewByIdOrRaise_api17_zh(self):
        vc = self.__mockTree(version=17, language='zh')
        vc.traverse(stream=self.openDevNull())
        vc.findViewByIdOrRaise('id/no_id/21')

    def testFindViewByIdOrRaise_nonExistentView(self):
        vc = self.__mockTree(dump=DUMP_SAMPLE_UI)
        try:
            vc.findViewByIdOrRaise('id/nonexistent')
            self.fail()
        except ViewNotFoundException:
            pass

    def testFindViewByIdOrRaise_nonExistentView_api17(self):
        vc = self.__mockTree(version=17)
        try:
            vc.findViewByIdOrRaise('id/nonexistent')
            self.fail()
        except ViewNotFoundException:
            pass

    def testFindViewByIdOrRaise_nonExistentView_api17_zh(self):
        vc = self.__mockTree(version=17, language='zh')
        try:
            vc.findViewByIdOrRaise('id/nonexistent')
            self.fail()
        except ViewNotFoundException:
            pass

    def testFindViewById_root(self):
        device = None
        root = View({'mID':'0'}, device)
        root.add(View({'mID':'1'}, device))
        root.add(View({'mID':'2'}, device))
        v3 = View({'mID':'3'}, device)
        root.add(v3)
        v35 = View({'mID':'5', 'getTag()':'v35'}, device)
        v3.add(v35)
        v4 = View({'mID':'4'}, device)
        root.add(v4)
        v45 = View({'mID':'5', 'getTag()':'v45'}, device)
        v4.add(v45)
        device = MockDevice()
        vc = ViewClient(device, device.serialno, adb=TRUE, autodump=False)
        self.assertNotEquals(None, vc)
        vc.root = root
        v5 = vc.findViewById('5')
        self.assertNotEqual(v5, None)
        self.assertEqual('v35', v5.getTag())
        v5 = vc.findViewById('5', root=v4)
        self.assertNotEqual(v5, None)
        self.assertEqual('v45', v5.getTag())
        v5 = vc.findViewById('5', root=v3)
        self.assertNotEqual(v5, None)
        self.assertEqual('v35', v5.getTag())

    def testFindViewById_viewFilter(self):
        vc = self.__mockTree(dump=DUMP_SAMPLE_UI)
        def vf(view):
            return view.getClass() == 'android.widget.ImageView'
        view = vc.findViewById('id/up', viewFilter=vf)
        self.assertNotEqual(view, None)

    def testFindViewById_viewFilterUnmatched(self):
        vc = self.__mockTree(dump=DUMP_SAMPLE_UI)
        def vf(view):
            return view.getClass() == 'android.widget.TextView'
        view = vc.findViewById('id/up', viewFilter=vf)
        self.assertEqual(view, None)

    def testFindViewByIdOrRaise_root(self):
        device = None
        root = View({'mID':'0'}, device)
        root.add(View({'mID':'1'}, device))
        root.add(View({'mID':'2'}, device))
        v3 = View({'mID':'3'}, device)
        root.add(v3)
        v35 = View({'mID':'5', 'getTag()':'v35'}, device)
        v3.add(v35)
        v4 = View({'mID':'4'}, device)
        root.add(v4)
        v45 = View({'mID':'5', 'getTag()':'v45'}, device)
        v4.add(v45)
        device = MockDevice()
        vc = ViewClient(device, device.serialno, adb=TRUE, autodump=False)
        self.assertNotEquals(None, vc)
        vc.root = root
        v5 = vc.findViewByIdOrRaise('5')
        self.assertEqual('v35', v5.getTag())
        v5 = vc.findViewByIdOrRaise('5', root=v4)
        self.assertEqual('v45', v5.getTag())
        v5 = vc.findViewByIdOrRaise('5', root=v3)
        self.assertEqual('v35', v5.getTag())

    def testFindViewByIdOrRaise_viewFilter(self):
        vc = self.__mockTree(dump=DUMP_SAMPLE_UI)
        def vf(view):
            return view.getClass() == 'android.widget.ImageView'
        view = vc.findViewByIdOrRaise('id/up', viewFilter=vf)

    def testFindViewByIdOrRaise_viewFilterUnmatched(self):
        vc = self.__mockTree(dump=DUMP_SAMPLE_UI)
        def vf(view):
            return view.getClass() == 'android.widget.TextView'
        try:
            view = vc.findViewByIdOrRaise('id/up', viewFilter=vf)
        except ViewNotFoundException:
            pass

    def testFindViewWithText_root(self):
        device = None
        root = View({'text:mText':'0'}, device)
        root.add(View({'text:mText':'1'}, device))
        root.add(View({'text:mText':'2'}, device))
        v3 = View({'text:mText':'3'}, device)
        root.add(v3)
        v35 = View({'text:mText':'5', 'getTag()':'v35'}, device)
        v3.add(v35)
        v4 = View({'text:mText':'4'}, device)
        root.add(v4)
        v45 = View({'text:mText':'5', 'getTag()':'v45'}, device)
        v4.add(v45)
        device = MockDevice()
        vc = ViewClient(device, device.serialno, adb=TRUE, autodump=False)
        self.assertNotEquals(None, vc)
        vc.root = root
        v5 = vc.findViewWithText('5')
        self.assertNotEqual(v5, None)
        self.assertEqual('v35', v5.getTag())
        v5 = vc.findViewWithText('5', root=v4)
        self.assertNotEqual(v5, None)
        self.assertEqual('v45', v5.getTag())
        v5 = vc.findViewWithText('5', root=v3)
        self.assertNotEqual(v5, None)
        self.assertEqual('v35', v5.getTag())

    def testFindViewWithText_regexRoot(self):
        device = None
        root = View({'text:mText':'0'}, device)
        root.add(View({'text:mText':'1'}, device))
        root.add(View({'text:mText':'2'}, device))
        v3 = View({'text:mText':'3'}, device)
        root.add(v3)
        v35 = View({'text:mText':'5', 'getTag()':'v35'}, device)
        v3.add(v35)
        v4 = View({'text:mText':'4'}, device)
        root.add(v4)
        v45 = View({'text:mText':'5', 'getTag()':'v45'}, device)
        v4.add(v45)
        device = MockDevice()
        vc = ViewClient(device, device.serialno, adb=TRUE, autodump=False)
        self.assertNotEquals(None, vc)
        vc.root = root
        v5 = vc.findViewWithText(re.compile('[5]'))
        self.assertNotEqual(v5, None)
        self.assertEqual('v35', v5.getTag())
        v5 = vc.findViewWithText(re.compile('[5]'), root=v4)
        self.assertNotEqual(v5, None)
        self.assertEqual('v45', v5.getTag())
        v5 = vc.findViewWithText(re.compile('[5]'), root=v3)
        self.assertNotEqual(v5, None)
        self.assertEqual('v35', v5.getTag())

    def testFindViewWithTextOrRaise_root(self):
        device = None
        root = View({'text:mText':'0'}, device)
        root.add(View({'text:mText':'1'}, device))
        root.add(View({'text:mText':'2'}, device))
        v3 = View({'text:mText':'3'}, device)
        root.add(v3)
        v35 = View({'text:mText':'5', 'getTag()':'v35'}, device)
        v3.add(v35)
        v4 = View({'text:mText':'4'}, device)
        root.add(v4)
        v45 = View({'text:mText':'5', 'getTag()':'v45'}, device)
        v4.add(v45)
        device = MockDevice()
        vc = ViewClient(device, device.serialno, adb=TRUE, autodump=False)
        self.assertNotEquals(None, vc)
        vc.root = root
        v5 = vc.findViewWithTextOrRaise('5')
        self.assertEqual('v35', v5.getTag())
        v5 = vc.findViewWithTextOrRaise('5', root=v4)
        self.assertEqual('v45', v5.getTag())
        v5 = vc.findViewWithTextOrRaise('5', root=v3)
        self.assertEqual('v35', v5.getTag())

    def testFindViewWithTextOrRaise_root_disappearingView(self):
        device = None
        root = View({'text:mText':'0'}, device)
        root.add(View({'text:mText':'1'}, device))
        root.add(View({'text:mText':'2'}, device))
        v3 = View({'text:mText':'3'}, device)
        root.add(v3)
        v35 = View({'text:mText':'5', 'getTag()':'v35'}, device)
        v3.add(v35)
        v4 = View({'text:mText':'4'}, device)
        root.add(v4)
        v45 = View({'text:mText':'5', 'getTag()':'v45'}, device)
        v4.add(v45)
        device = MockDevice()
        vc = ViewClient(device, device.serialno, adb=TRUE, autodump=False)
        self.assertNotEquals(None, vc)
        vc.root = root
        v5 = vc.findViewWithTextOrRaise('5')
        self.assertEqual('v35', v5.getTag())
        v5 = vc.findViewWithTextOrRaise('5', root=v4)
        self.assertEqual('v45', v5.getTag())
        v5 = vc.findViewWithTextOrRaise('5', root=v3)
        self.assertEqual('v35', v5.getTag())
        # Then remove v4 and its children
        root.children.remove(v4)
        #vc.dump()
        v4 = vc.findViewWithText('4')
        self.assertEqual(v4, None, "v4 has not disappeared")

    def testFindViewWithTextOrRaise_rootNonExistent(self):
        device = None
        root = View({'text:mText':'0'}, device)
        root.add(View({'text:mText':'1'}, device))
        root.add(View({'text:mText':'2'}, device))
        v3 = View({'text:mText':'3'}, device)
        root.add(v3)
        v35 = View({'text:mText':'5', 'getTag()':'v35'}, device)
        v3.add(v35)
        v4 = View({'text:mText':'4'}, device)
        root.add(v4)
        v45 = View({'text:mText':'5', 'getTag()':'v45'}, device)
        v4.add(v45)
        device = MockDevice()
        vc = ViewClient(device, device.serialno, adb=TRUE, autodump=False)
        self.assertNotEquals(None, vc)
        vc.root = root
        try:
            vc.findViewWithTextOrRaise('Non Existent', root=v4)
            self.fail()
        except ViewNotFoundException:
            pass

    def testFindViewWithTextOrRaise_api17(self):
        vc = self.__mockTree(version=17)
        vc.findViewWithTextOrRaise("Apps")

    def openDevNull(self):
        return open('/dev/null', 'a+')

    def testFindViewWithTextOrRaise_api17_zh(self):
        vc = self.__mockTree(version=17, language='zh')
        vc.traverse(transform=ViewClient.TRAVERSE_CIT, stream=self.openDevNull())
        vc.findViewWithTextOrRaise(u'语言')

    def testFindViewWithTextOrRaise_nonExistent_api17(self):
        vc = self.__mockTree(version=17)
        try:
            vc.findViewWithTextOrRaise('nonexistent text')
            self.fail()
        except ViewNotFoundException:
            pass

    def testFindViewWithTextOrRaise_nonExistent_api17_zh(self):
        vc = self.__mockTree(version=17, language='zh')
        try:
            vc.findViewWithTextOrRaise(u'不存在的文本')
            self.fail()
        except ViewNotFoundException:
            pass

    def testFindViewWithContentDescription_root(self):
        device = None
        root = View({'text:mText':'0', 'content-desc':'CD0'}, device)
        root.add(View({'text:mText':'1', 'content-desc':'CD1'}, device))
        root.add(View({'text:mText':'2', 'content-desc':'CD2'}, device))
        v3 = View({'text:mText':'3', 'content-desc':'CD3'}, device)
        root.add(v3)
        v35 = View({'text:mText':'35', 'content-desc':'CD35'}, device)
        v3.add(v35)
        v4 = View({'text:mText':'4', 'conent-desc':'CD4'}, device)
        root.add(v4)
        v45 = View({'text:mText':'45', 'content-desc':'CD45'}, device)
        v4.add(v45)
        device = MockDevice()
        vc = ViewClient(device, device.serialno, adb=TRUE, autodump=False)
        self.assertNotEquals(None, vc)
        vc.root = root
        v45 = vc.findViewWithContentDescription('CD45')
        self.assertNotEqual(v45, None)
        self.assertEqual('45', v45.getText())
        v45 = vc.findViewWithContentDescription('CD45', root=v4)
        self.assertNotEqual(v45, None)
        self.assertEqual('45', v45.getText())
        v35 = vc.findViewWithContentDescription('CD35', root=v3)
        self.assertNotEqual(v35, None)
        self.assertEqual('35', v35.getText())

    def testFindViewWithContentDescription_regexRoot(self):
        device = None
        root = View({'text:mText':'0', 'content-desc':'CD0'}, device)
        root.add(View({'text:mText':'1', 'content-desc':'CD1'}, device))
        root.add(View({'text:mText':'2', 'content-desc':'CD2'}, device))
        v3 = View({'text:mText':'3', 'content-desc':'CD3'}, device)
        root.add(v3)
        v35 = View({'text:mText':'35', 'content-desc':'CD35'}, device)
        v3.add(v35)
        v4 = View({'text:mText':'4', 'conent-desc':'CD4'}, device)
        root.add(v4)
        v45 = View({'text:mText':'45', 'content-desc':'CD45'}, device)
        v4.add(v45)
        device = MockDevice()
        vc = ViewClient(device, device.serialno, adb=TRUE, autodump=False)
        self.assertNotEquals(None, vc)
        vc.root = root
        v45 = vc.findViewWithContentDescription(re.compile('CD4\d'))
        self.assertNotEqual(v45, None)
        self.assertEqual('45', v45.getText())
        v45 = vc.findViewWithContentDescription(re.compile('CD4\d'), root=v4)
        self.assertNotEqual(v45, None)
        self.assertEqual('45', v45.getText())
        v35 = vc.findViewWithContentDescription(re.compile('CD3\d'), root=v3)
        self.assertNotEqual(v35, None)
        self.assertEqual('35', v35.getText())

    def testFindViewWithContentDescriptionOrRaise_root(self):
        device = None
        root = View({'text:mText':'0', 'content-desc':'CD0'}, device)
        root.add(View({'text:mText':'1', 'content-desc':'CD1'}, device))
        root.add(View({'text:mText':'2', 'content-desc':'CD2'}, device))
        v3 = View({'text:mText':'3', 'content-desc':'CD3'}, device)
        root.add(v3)
        v35 = View({'text:mText':'35', 'content-desc':'CD35'}, device)
        v3.add(v35)
        v4 = View({'text:mText':'4', 'conent-desc':'CD4'}, device)
        root.add(v4)
        v45 = View({'text:mText':'45', 'content-desc':'CD45'}, device)
        v4.add(v45)
        device = MockDevice()
        vc = ViewClient(device, device.serialno, adb=TRUE, autodump=False)
        self.assertNotEquals(None, vc)
        vc.root = root
        v45 = vc.findViewWithContentDescriptionOrRaise('CD45')
        self.assertEqual('45', v45.getText())
        v45 = vc.findViewWithContentDescriptionOrRaise('CD45', root=v4)
        self.assertEqual('45', v45.getText())
        v35 = vc.findViewWithContentDescriptionOrRaise('CD35', root=v3)
        self.assertEqual('35', v35.getText())

    def testFindViewWithContentDescriptionOrRaise_rootNonExistent(self):
        device = None
        root = View({'text:mText':'0', 'content-desc':'CD0'}, device)
        root.add(View({'text:mText':'1', 'content-desc':'CD1'}, device))
        root.add(View({'text:mText':'2', 'content-desc':'CD2'}, device))
        v3 = View({'text:mText':'3', 'content-desc':'CD3'}, device)
        root.add(v3)
        v35 = View({'text:mText':'35', 'content-desc':'CD35'}, device)
        v3.add(v35)
        v4 = View({'text:mText':'4', 'conent-desc':'CD4'}, device)
        root.add(v4)
        v45 = View({'text:mText':'45', 'content-desc':'CD45'}, device)
        v4.add(v45)
        device = MockDevice()
        vc = ViewClient(device, device.serialno, adb=TRUE, autodump=False)
        self.assertNotEquals(None, vc)
        vc.root = root
        try:
            vc.findViewWithContentDescriptionOrRaise('Non Existent', root=v4)
            self.fail()
        except ViewNotFoundException:
            pass

    def testFindViewWithContentDescriptionOrRaiseExceptionMessage_regexpRoot(self):
        device = None
        root = View({'text:mText':'0', 'content-desc':'CD0'}, device)
        root.add(View({'text:mText':'1', 'content-desc':'CD1'}, device))
        root.add(View({'text:mText':'2', 'content-desc':'CD2'}, device))
        v3 = View({'text:mText':'3', 'content-desc':'CD3'}, device)
        root.add(v3)
        v35 = View({'text:mText':'35', 'content-desc':'CD35'}, device)
        v3.add(v35)
        v4 = View({'text:mText':'4', 'conent-desc':'CD4'}, device)
        root.add(v4)
        v45 = View({'text:mText':'45', 'content-desc':'CD45'}, device)
        v4.add(v45)
        device = MockDevice()
        vc = ViewClient(device, device.serialno, adb=TRUE, autodump=False)
        self.assertNotEquals(None, vc)
        vc.root = root
        try:
            vc.findViewWithContentDescriptionOrRaise(re.compile('Non Existent'), root=v4)
            self.fail()
        except ViewNotFoundException, e:
            self.assertNotEquals(None, re.search("that matches 'Non Existent'", e.message))

    def testUiAutomatorDump(self):
        device = MockDevice(version=16)
        vc = ViewClient(device, device.serialno, adb=TRUE, autodump=True)

    def testUiAutomatorKilled(self):
        device = MockDevice(version=16, uiautomatorkilled=True)
        try:
            vc = ViewClient(device, device.serialno, adb=TRUE, autodump=True, ignoreuiautomatorkilled=True)
        except Exception, e:
            self.assertIsNotNone(re.search('''ERROR: UiAutomator output contains no valid information. UiAutomator was killed, no reason given.''', str(e)))

    def testUiViewServerDump(self):
        device = None
        try:
            device = MockDevice(version=15, startviewserver=True)
            vc = ViewClient(device, device.serialno, adb=TRUE, autodump=False)
            vc.dump()
            vc.findViewByIdOrRaise('id/home')
        finally:
            if device:
                device.shutdownMockViewServer()

    def testUiViewServerDump_windowStr(self):
        device = None
        try:
            device = MockDevice(version=15, startviewserver=True)
            vc = ViewClient(device, device.serialno, adb=TRUE, autodump=False)
            vc.dump(window='StatusBar')
            vc.findViewByIdOrRaise('id/status_bar')
        finally:
            if device:
                device.shutdownMockViewServer()

    def testUiViewServerDump_windowInt(self):
        device = None
        try:
            device = MockDevice(version=15, startviewserver=True)
            vc = ViewClient(device, device.serialno, adb=TRUE, autodump=False)
            vc.dump(window=0xb52f7c88)
            vc.findViewByIdOrRaise('id/status_bar')
        finally:
            if device:
                device.shutdownMockViewServer()

    def testUiViewServerDump_windowIntStr(self):
        device = None
        try:
            device = MockDevice(version=15, startviewserver=True)
            vc = ViewClient(device, device.serialno, adb=TRUE, autodump=False)
            vc.dump(window='0xb52f7c88')
            vc.findViewByIdOrRaise('id/status_bar')
        finally:
            if device:
                device.shutdownMockViewServer()

    def testUiViewServerDump_windowIntM1(self):
        device = None
        try:
            device = MockDevice(version=15, startviewserver=True)
            vc = ViewClient(device, device.serialno, adb=TRUE, autodump=False)
            vc.dump(window=-1)
            vc.findViewByIdOrRaise('id/home')
        finally:
            if device:
                device.shutdownMockViewServer()

    def testFindViewsContainingPoint_api15(self):
        device = None
        try:
            device = MockDevice(version=15, startviewserver=True)
            vc = ViewClient(device, device.serialno, adb=TRUE)
            list = vc.findViewsContainingPoint((200, 200))
            self.assertNotEquals(None, list)
            self.assertNotEquals(0, len(list))
        finally:
            if device:
                device.shutdownMockViewServer()

    def testFindViewsContainingPoint_api17(self):
        device = MockDevice(version=17)
        vc = ViewClient(device, device.serialno, adb=TRUE)
        list = vc.findViewsContainingPoint((55, 75))
        self.assertNotEquals(None, list)
        self.assertNotEquals(0, len(list))

    def testFindViewsContainingPoint_filterApi15(self):
        device = None
        try:
            device = MockDevice(version=15, startviewserver=True)
            vc = ViewClient(device, device.serialno, adb=TRUE)
            list = vc.findViewsContainingPoint((200, 200), _filter=View.isClickable)
            self.assertNotEquals(None, list)
            self.assertNotEquals(0, len(list))
        finally:
            if device:
                device.shutdownMockViewServer()

    def testFindViewsContainingPoint_filterApi17(self):
        device = MockDevice(version=17)
        vc = ViewClient(device, device.serialno, adb=TRUE)
        list = vc.findViewsContainingPoint((55, 75), _filter=View.isClickable)
        self.assertNotEquals(None, list)
        self.assertNotEquals(0, len(list))

if __name__ == "__main__":
    print >> sys.stderr, "ViewClient.__main__:"
    print >> sys.stderr, "argv=", sys.argv
    #import sys;sys.argv = ['', 'Test.testName']
    #sys.argv.append('ViewClientTest.testFindViewsContainingPoint_filterApi17')
    unittest.main()
