bug 1280326 - make MockedOpen case-insensitive on Windows. r?gps draft
authorTed Mielczarek <ted@mielczarek.org>
Tue, 28 Jun 2016 16:11:33 -0400
changeset 382450 5366ad0ebaeb9c478b719a79b9df82c1231503ac
parent 382391 b69a5bbb5e40bd426e35222baa600b481e50d265
child 524192 4c2bc380613d5b6d67d0234f90e4e6ef1ab950df
push id21721
push usertmielczarek@mozilla.com
push dateWed, 29 Jun 2016 17:37:43 +0000
reviewersgps
bugs1280326
milestone50.0a1
bug 1280326 - make MockedOpen case-insensitive on Windows. r?gps MozReview-Commit-ID: O26u2kVrSk
config/mozunit.py
--- a/config/mozunit.py
+++ b/config/mozunit.py
@@ -2,16 +2,17 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from unittest import TextTestRunner as _TestRunner, TestResult as _TestResult
 import unittest
 import inspect
 from StringIO import StringIO
 import os
+import sys
 
 '''Helper to make python unit tests report the way that the Mozilla
 unit test infrastructure expects tests to report.
 
 Usage:
 
 import unittest
 import mozunit
@@ -102,16 +103,27 @@ class MockedFile(StringIO):
         StringIO.close(self)
 
     def __enter__(self):
         return self
 
     def __exit__(self, type, value, traceback):
         self.close()
 
+def normcase(path):
+    '''
+    Normalize the case of `path`.
+
+    Don't use `os.path.normcase` because that also normalizes forward slashes
+    to backslashes on Windows.
+    '''
+    if sys.platform.startswith('win'):
+        return path.lower()
+    return path
+
 class MockedOpen(object):
     '''
     Context manager diverting the open builtin such that opening files
     can open "virtual" file instances given when creating a MockedOpen.
 
     with MockedOpen({'foo': 'foo', 'bar': 'bar'}):
         f = open('foo', 'r')
 
@@ -124,20 +136,20 @@ class MockedOpen(object):
     with MockedOpen():
         f = open('foo', 'w')
         f.write('foo')
     self.assertRaises(Exception,f.open('foo', 'r'))
     '''
     def __init__(self, files = {}):
         self.files = {}
         for name, content in files.iteritems():
-            self.files[os.path.abspath(name)] = content
+            self.files[normcase(os.path.abspath(name))] = content
 
     def __call__(self, name, mode = 'r'):
-        absname = os.path.abspath(name)
+        absname = normcase(os.path.abspath(name))
         if 'w' in mode:
             file = MockedFile(self, absname)
         elif absname in self.files:
             file = MockedFile(self, absname, self.files[absname])
         elif 'a' in mode:
             file = MockedFile(self, absname, self.open(name, 'r').read())
         else:
             file = self.open(name, mode)
@@ -164,26 +176,28 @@ class MockedOpen(object):
         os.path.isfile = self._orig_path_isfile
 
     def _wrapped_exists(self, p):
         return (self._wrapped_isfile(p) or
                 self._wrapped_isdir(p) or
                 self._orig_path_exists(p))
 
     def _wrapped_isfile(self, p):
+        p = normcase(p)
         if p in self.files:
             return True
 
         abspath = os.path.abspath(p)
         if abspath in self.files:
             return True
 
         return self._orig_path_isfile(p)
 
     def _wrapped_isdir(self, p):
+        p = normcase(p)
         p = p if p.endswith(('/', '\\')) else p + os.sep
         if any(f.startswith(p) for f in self.files):
             return True
 
         abspath = os.path.abspath(p) + os.sep
         if any(f.startswith(abspath) for f in self.files):
             return True