1 # Copyright (C) 2012 Google, Inc. 2 # 3 # Redistribution and use in source and binary forms, with or without 4 # modification, are permitted provided that the following conditions 5 # are met: 6 # 1. Redistributions of source code must retain the above copyright 7 # notice, this list of conditions and the following disclaimer. 8 # 2. Redistributions in binary form must reproduce the above copyright 9 # notice, this list of conditions and the following disclaimer in the 10 # documentation and/or other materials provided with the distribution. 11 # 12 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND 13 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15 # DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR 16 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 17 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 18 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 19 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 20 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 21 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 23 import logging 24 import unittest 25 26 from webkitpy.common.system.filesystem_mock import MockFileSystem 27 from webkitpy.common.system.outputcapture import OutputCapture 28 from webkitpy.test.finder import Finder 29 30 31 class FinderTest(unittest.TestCase): 32 def setUp(self): 33 files = { 34 '/foo/bar/baz.py': '', 35 '/foo/bar/baz_unittest.py': '', 36 '/foo2/bar2/baz2.py': '', 37 '/foo2/bar2/baz2.pyc': '', 38 '/foo2/bar2/baz2_integrationtest.py': '', 39 '/foo2/bar2/missing.pyc': '', 40 '/tmp/another_unittest.py': '', 41 } 42 self.fs = MockFileSystem(files) 43 self.finder = Finder(self.fs) 44 self.finder.add_tree('/foo', 'bar') 45 self.finder.add_tree('/foo2') 46 47 # Here we have to jump through a hoop to make sure test-webkitpy doesn't log 48 # any messages from these tests :(. 49 self.root_logger = logging.getLogger() 50 self.log_levels = [] 51 self.log_handlers = self.root_logger.handlers[:] 52 for handler in self.log_handlers: 53 self.log_levels.append(handler.level) 54 handler.level = logging.CRITICAL 55 56 def tearDown(self): 57 for handler in self.log_handlers: 58 handler.level = self.log_levels.pop(0) 59 60 def test_additional_system_paths(self): 61 self.assertEqual(self.finder.additional_paths(['/usr']), 62 ['/foo', '/foo2']) 63 64 def test_is_module(self): 65 self.assertTrue(self.finder.is_module('bar.baz')) 66 self.assertTrue(self.finder.is_module('bar2.baz2')) 67 self.assertTrue(self.finder.is_module('bar2.baz2_integrationtest')) 68 69 # Missing the proper namespace. 70 self.assertFalse(self.finder.is_module('baz')) 71 72 def test_to_module(self): 73 self.assertEqual(self.finder.to_module('/foo/test.py'), 'test') 74 self.assertEqual(self.finder.to_module('/foo/bar/test.py'), 'bar.test') 75 self.assertEqual(self.finder.to_module('/foo/bar/pytest.py'), 'bar.pytest') 76 77 def test_clean(self): 78 self.assertTrue(self.fs.exists('/foo2/bar2/missing.pyc')) 79 self.finder.clean_trees() 80 self.assertFalse(self.fs.exists('/foo2/bar2/missing.pyc')) 81 82 def check_names(self, names, expected_names, find_all=True): 83 self.assertEqual(self.finder.find_names(names, find_all), expected_names) 84 85 def test_default_names(self): 86 self.check_names([], ['bar.baz_unittest', 'bar2.baz2_integrationtest'], find_all=True) 87 self.check_names([], ['bar.baz_unittest', 'bar2.baz2_integrationtest'], find_all=False) 88 89 # Should return the names given it, even if they don't exist. 90 self.check_names(['foobar'], ['foobar'], find_all=False) 91 92 def test_paths(self): 93 self.fs.chdir('/foo/bar') 94 self.check_names(['baz_unittest.py'], ['bar.baz_unittest']) 95 self.check_names(['./baz_unittest.py'], ['bar.baz_unittest']) 96 self.check_names(['/foo/bar/baz_unittest.py'], ['bar.baz_unittest']) 97 self.check_names(['.'], ['bar.baz_unittest']) 98 self.check_names(['../../foo2/bar2'], ['bar2.baz2_integrationtest']) 99 100 self.fs.chdir('/') 101 self.check_names(['bar'], ['bar.baz_unittest']) 102 self.check_names(['/foo/bar/'], ['bar.baz_unittest']) 103 104 # This works 'by accident' since it maps onto a package. 105 self.check_names(['bar/'], ['bar.baz_unittest']) 106 107 # This should log an error, since it's outside the trees. 108 oc = OutputCapture() 109 oc.set_log_level(logging.ERROR) 110 oc.capture_output() 111 try: 112 self.check_names(['/tmp/another_unittest.py'], []) 113 finally: 114 _, _, logs = oc.restore_output() 115 self.assertIn('another_unittest.py', logs) 116 117 # Paths that don't exist are errors. 118 oc.capture_output() 119 try: 120 self.check_names(['/foo/bar/notexist_unittest.py'], []) 121 finally: 122 _, _, logs = oc.restore_output() 123 self.assertIn('notexist_unittest.py', logs) 124 125 # Names that don't exist are caught later, at load time. 126 self.check_names(['bar.notexist_unittest'], ['bar.notexist_unittest']) 127