PY2/3 update signatures and simplify logic so we have expected signitures per version...
authorWilliam Deegan <bill@baddogconsulting.com>
Tue, 1 Aug 2017 16:48:22 +0000 (09:48 -0700)
committerWilliam Deegan <bill@baddogconsulting.com>
Tue, 1 Aug 2017 16:48:22 +0000 (09:48 -0700)
src/engine/SCons/ActionTests.py

index ba3d844597c681a30133bf60d601e2e280b76eec..a5432c6644f914efbc4ff4c5fb84f05cdf78e993 100644 (file)
@@ -98,9 +98,7 @@ scons_env = SCons.Environment.Environment()
 
 # Capture all the stuff the Actions will print,
 # so it doesn't clutter the output.
-
-# TODO.. uncomment
-# sys.stdout = io.StringIO()
+sys.stdout = io.StringIO()
 
 class CmdStringHolder(object):
     def __init__(self, cmd, literal=None):
@@ -1441,6 +1439,17 @@ class CommandGeneratorActionTestCase(unittest.TestCase):
                 b"0, 0, 0, 0,(),(),(d\x00\x00S),(),()",
                 ]
 
+        # Since the python bytecode has per version differences, we need different expected results per version
+        func_matches = {
+            (2,7) : bytearray(b'0, 0, 0, 0,(N.),(),(d\x00\x00S),(),()'),
+            (3,5) : bytearray(b'0, 0, 0, 0,(N.),(),(d\x00\x00S),(),()'),
+            (3,6) : bytearray(b'0, 0, 0, 0,(N.),(),(d\x00S\x00),(),()'),
+        }
+
+        # c = SCons.Action._function_contents(func1)
+        # assert c == expected[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected \n"+"\n"+repr(expected[sys.version_info[:2]])
+
+
         meth_matches = [
             b"1, 1, 0, 0,(),(),(d\000\000S),(),()",
             b"1, 1, 0, 0,(),(),(d\x00\x00S),(),()",
@@ -1456,11 +1465,11 @@ class CommandGeneratorActionTestCase(unittest.TestCase):
 
         a = self.factory(f_global)
         c = a.get_contents(target=[], source=[], env=env)
-        assert c in func_matches, "Got\n"+repr(c)+"\nExpected one of \n"+"\n".join([repr(f) for f in func_matches])
+        assert c == func_matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected \n"+repr(func_matches[sys.version_info[:2]])
 
         a = self.factory(f_local)
         c = a.get_contents(target=[], source=[], env=env)
-        assert c in func_matches, "Got\n"+repr(c)+"\nExpected one of \n"+"\n".join([repr(f) for f in func_matches])
+        assert c == func_matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected \n"+repr(func_matches[sys.version_info[:2]])
 
         def f_global(target, source, env, for_signature):
             return SCons.Action.Action(GlobalFunc, varlist=['XYZ'])
@@ -1468,7 +1477,7 @@ class CommandGeneratorActionTestCase(unittest.TestCase):
         def f_local(target, source, env, for_signature):
             return SCons.Action.Action(LocalFunc, varlist=['XYZ'])
 
-        matches_foo = [x + b"foo" for x in func_matches]
+        matches_foo = func_matches[sys.version_info[:2]] + b'foo'
 
         a = self.factory(f_global)
         c = a.get_contents(target=[], source=[], env=env)
@@ -1598,52 +1607,48 @@ class FunctionActionTestCase(unittest.TestCase):
         def LocalFunc():
             pass
 
-        if TestCmd.IS_PY3 and TestCmd.IS_WINDOWS:
-            func_matches = [
-                b'0, 0, 0, 0,(),(),(d\x00S\x00),(),()',  # py 3.6
-                b'0, 0, 0, 0,(),(),(d\x00\x00S),(),()'   # py 3.5
-                ]
-            meth_matches = [
-                b'1, 1, 0, 0,(),(),(d\x00S\x00),(),()',  # py 3.6
-                b'1, 1, 0, 0,(),(),(d\x00\x00S),(),()',  # py 3.5
-            ]
-
-        else:
-            func_matches = [
-                b"0, 0, 0, 0,(),(),(d\000\000S),(),()",
-                b"0, 0, 0, 0,(),(),(d\x00\x00S),(),()",
-                ]
+        func_matches = {
+            (2,7) : bytearray(b'0, 0, 0, 0,(N.),(),(d\x00\x00S),(),()'),
+            (3,5) : bytearray(b'0, 0, 0, 0,(N.),(),(d\x00\x00S),(),()'),
+            (3,6) : bytearray(b'0, 0, 0, 0,(N.),(),(d\x00S\x00),(),()'),
+        }
 
-            meth_matches = [
-                b"1, 1, 0, 0,(),(),(d\000\000S),(),()",
-                b"1, 1, 0, 0,(),(),(d\x00\x00S),(),()",
-            ]
+        meth_matches = {
+            (2,7) : bytearray(b'1, 1, 0, 0,(N.),(),(d\x00\x00S),(),()'),
+            (3,5) : bytearray(b'1, 1, 0, 0,(N.),(),(d\x00\x00S),(),()'),
+            (3,6) : bytearray(b'1, 1, 0, 0,(N.),(),(d\x00S\x00),(),()'),
+        }
 
         def factory(act, **kw):
             return SCons.Action.FunctionAction(act, kw)
 
         a = factory(GlobalFunc)
         c = a.get_contents(target=[], source=[], env=Environment())
-        assert c in func_matches, "Got\n"+repr(c)+"\nExpected one of \n"+"\n".join([repr(f) for f in func_matches])
+        assert c == func_matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(func_matches[sys.version_info[:2]])
 
 
         a = factory(LocalFunc)
         c = a.get_contents(target=[], source=[], env=Environment())
-        assert c in func_matches, repr(c)
+        assert c == func_matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(func_matches[sys.version_info[:2]])
 
-        matches_foo = [x + b"foo" for x in func_matches]
+        matches_foo = func_matches[sys.version_info[:2]] + b'foo'
 
         a = factory(GlobalFunc, varlist=['XYZ'])
         c = a.get_contents(target=[], source=[], env=Environment())
-        assert c in func_matches, repr(c)
+        assert c == func_matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(func_matches[sys.version_info[:2]])
+        # assert c in func_matches, repr(c)
+
         c = a.get_contents(target=[], source=[], env=Environment(XYZ='foo'))
-        assert c in matches_foo, repr(c)
+        assert c == matches_foo, repr(c)
 
         ##TODO: is this set of tests still needed?
         # Make sure a bare string varlist works
         a = factory(GlobalFunc, varlist='XYZ')
         c = a.get_contents(target=[], source=[], env=Environment())
-        assert c in func_matches, repr(c)
+        # assert c in func_matches, repr(c)
+        assert c == func_matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(func_matches[sys.version_info[:2]])
+
+
         c = a.get_contents(target=[], source=[], env=Environment(XYZ='foo'))
         assert c in matches_foo, repr(c)
 
@@ -1660,7 +1665,7 @@ class FunctionActionTestCase(unittest.TestCase):
         lc = LocalClass()
         a = factory(lc.LocalMethod)
         c = a.get_contents(target=[], source=[], env=Environment())
-        assert c in meth_matches,  "Got\n"+repr(c)+"\nExpected one of \n"+"\n".join([repr(f) for f in meth_matches])
+        assert c == meth_matches[sys.version_info[:2]],  "Got\n"+repr(c)+"\nExpected one of \n"+repr(meth_matches[sys.version_info[:2]])
 
     def test_strfunction(self):
         """Test the FunctionAction.strfunction() method
@@ -1826,16 +1831,23 @@ class LazyActionTestCase(unittest.TestCase):
         def LocalFunc():
             pass
 
-        if TestCmd.IS_PY3 and TestCmd.IS_WINDOWS:
-            func_matches = [
-                b'0, 0, 0, 0,(),(),(d\x00S\x00),(),()',
-                b'0, 0, 0, 0,(),(),(d\x00\x00S),(),()'
-                ]
-        else:
-            func_matches = [
-                b"0, 0, 0, 0,(),(),(d\000\000S),(),()",
-                b"0, 0, 0, 0,(),(),(d\x00\x00S),(),()",
-                ]
+
+        func_matches = {
+            (2,7) : bytearray(b'0, 0, 0, 0,(N.),(),(d\x00\x00S),(),()'),
+            (3,5) : bytearray(b'0, 0, 0, 0,(N.),(),(d\x00\x00S),(),()'),
+            (3,6) : bytearray(b'0, 0, 0, 0,(N.),(),(d\x00S\x00),(),()'),
+        }
+
+        # if TestCmd.IS_PY3 and TestCmd.IS_WINDOWS:
+        #     func_matches = [
+        #         b'0, 0, 0, 0,(),(),(d\x00S\x00),(),()',
+        #         b'0, 0, 0, 0,(),(),(d\x00\x00S),(),()'
+        #         ]
+        # else:
+        #     func_matches = [
+        #         b"0, 0, 0, 0,(),(),(d\000\000S),(),()",
+        #         b"0, 0, 0, 0,(),(),(d\x00\x00S),(),()",
+        #         ]
 
         meth_matches = [
             b"1, 1, 0, 0,(),(),(d\000\000S),(),()",
@@ -1850,17 +1862,22 @@ class LazyActionTestCase(unittest.TestCase):
 
         env = Environment(FOO = factory(GlobalFunc))
         c = a.get_contents(target=[], source=[], env=env)
-        assert c in func_matches, "Got\n"+repr(c)+"\nExpected one of \n"+"\n".join([repr(f) for f in func_matches])
+        # assert c in func_matches, "Got\n"+repr(c)+"\nExpected one of \n"+"\n".join([repr(f) for f in func_matches])
+        assert c == func_matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(func_matches[sys.version_info[:2]])
+
+
 
         env = Environment(FOO = factory(LocalFunc))
         c = a.get_contents(target=[], source=[], env=env)
-        assert c in func_matches, repr(c)
+        assert c == func_matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(func_matches[sys.version_info[:2]])
+
+        # matches_foo = [x + b"foo" for x in func_matches]
+        matches_foo = func_matches[sys.version_info[:2]] + b'foo'
 
-        matches_foo = [x + b"foo" for x in func_matches]
 
         env = Environment(FOO = factory(GlobalFunc, varlist=['XYZ']))
         c = a.get_contents(target=[], source=[], env=env)
-        assert c in func_matches, repr(c)
+        assert c == func_matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(func_matches[sys.version_info[:2]])
 
         env['XYZ'] = 'foo'
         c = a.get_contents(target=[], source=[], env=env)
@@ -1883,32 +1900,23 @@ class ActionCallerTestCase(unittest.TestCase):
         def LocalFunc():
             pass
 
-        if TestCmd.IS_PY3 and TestCmd.IS_WINDOWS:
-            matches = [
-                b'd\x00S\x00',
-                b'd\x00\x00S'
-            ]
-        else:
-            matches = [
-                b"d\000\000S",
-                b"d\\x00\\x00S"
-            ]
+
+        matches = {
+            (2,7) : b'd\x00\x00S',
+            (3,5) : b'd\x00\x00S',
+            (3,6) : b'd\x00S\x00',
+        }
+
 
         af = SCons.Action.ActionFactory(GlobalFunc, strfunc)
         ac = SCons.Action.ActionCaller(af, [], {})
         c = ac.get_contents([], [], Environment())
-        assert c in matches, "Got\n"+repr(c)+"\nExpected one of \n"+"\n".join([repr(f) for f in matches])
+        assert c == matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(matches[sys.version_info[:2]])
 
         af = SCons.Action.ActionFactory(LocalFunc, strfunc)
         ac = SCons.Action.ActionCaller(af, [], {})
         c = ac.get_contents([], [], Environment())
-        assert c in matches, "Got\n"+repr(c)+"\nExpected one of \n"+"\n".join([repr(f) for f in matches])
-
-        # TODO: Same as above, why redefine?
-        # matches = [
-        #     b'd\000\000S',
-        #     b"d\x00\x00S"
-        # ]
+        assert c == matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(matches[sys.version_info[:2]])
 
         class LocalActFunc(object):
             def __call__(self):
@@ -1917,12 +1925,12 @@ class ActionCallerTestCase(unittest.TestCase):
         af = SCons.Action.ActionFactory(GlobalActFunc(), strfunc)
         ac = SCons.Action.ActionCaller(af, [], {})
         c = ac.get_contents([], [], Environment())
-        assert c in matches, "C [%s] not in matches [%s]"%(repr(c),matches)
+        assert c == matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(matches[sys.version_info[:2]])
 
         af = SCons.Action.ActionFactory(LocalActFunc(), strfunc)
         ac = SCons.Action.ActionCaller(af, [], {})
         c = ac.get_contents([], [], Environment())
-        assert c in matches, repr(c)
+        assert c == matches[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected one of \n"+repr(matches[sys.version_info[:2]])
 
         matches = [
             b"<built-in function str>",
@@ -2074,13 +2082,15 @@ class ObjectContentsTestCase(unittest.TestCase):
             """A test function"""
             return a
 
+        # Since the python bytecode has per version differences, we need different expected results per version
+        expected = {
+            (2,7) : bytearray(b'3, 3, 0, 0,(A test function),(),(|\x00\x00S),(),()'),
+            (3,5) : bytearray(b'3, 3, 0, 0,(A test function),(),(|\x00\x00S),(),()'),
+            (3,6) : bytearray(b'3, 3, 0, 0,(A test function),(),(|\x00S\x00),(),()'),
+        }
+
         c = SCons.Action._function_contents(func1)
-        if TestCmd.IS_PY3 and TestCmd.IS_WINDOWS:
-            expected = [b'3, 3, 0, 0,(),(),(|\x00S\x00),(),()',
-                        b'3, 3, 0, 0,(),(),(|\x00\x00S),(),()']
-        else:
-            expected = [b'3, 3, 0, 0,(),(),(|\x00\x00S),(),()']
-        assert c in expected, "Got\n"+repr(c)+"\nExpected one of \n"+"\n".join([repr(e) for e in expected])
+        assert c == expected[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected \n"+"\n"+repr(expected[sys.version_info[:2]])
 
 
     def test_object_contents(self):
@@ -2093,31 +2103,29 @@ class ObjectContentsTestCase(unittest.TestCase):
         # c = SCons.Action._object_instance_content(o)
 
         # Since the python bytecode has per version differences, we need different expected results per version
-        if TestCmd.IS_PY3:
-            if sys.version_info[:2] == (3,5):
-                expected = bytearray(b"{TestClass:__main__}[[[(<class \'object\'>, ()), [(<class \'__main__.TestClass\'>, (<class \'object\'>,))]]]]{{1, 1, 0, 0,({str:builtins}[[[(<class \'object\'>, ()), [(<class \'str\'>, (<class \'object\'>,))]]]]{{}}{{{}}},{str:builtins}[[[(<class \'object\'>, ()), [(<class \'str\'>, (<class \'object\'>,))]]]]{{}}{{{}}}),({str:builtins}[[[(<class \'object\'>, ()), [(<class \'str\'>, (<class \'object\'>,))]]]]{{}}{{{}}},{str:builtins}[[[(<class \'object\'>, ()), [(<class \'str\'>, (<class \'object\'>,))]]]]{{}}{{{}}}),(d\x01\x00|\x00\x00_\x00\x00d\x02\x00|\x00\x00_\x01\x00d\x00\x00S),(),(),2, 2, 0, 0,(),(),(d\x00\x00S),(),()}}{{{a=a,b=b}}}")
-            elif sys.version_info[:2] == (3,6):
-                expected = bytearray(b"{TestClass:__main__}[[[(<class \'object\'>, ()), [(<class \'__main__.TestClass\'>, (<class \'object\'>,))]]]]{{1, 1, 0, 0,({str:builtins}[[[(<class \'object\'>, ()), [(<class \'str\'>, (<class \'object\'>,))]]]]{{}}{{{}}},{str:builtins}[[[(<class \'object\'>, ()), [(<class \'str\'>, (<class \'object\'>,))]]]]{{}}{{{}}}),({str:builtins}[[[(<class \'object\'>, ()), [(<class \'str\'>, (<class \'object\'>,))]]]]{{}}{{{}}},{str:builtins}[[[(<class \'object\'>, ()), [(<class \'str\'>, (<class \'object\'>,))]]]]{{}}{{{}}}),(d\x01|\x00_\x00d\x02|\x00_\x01d\x00S\x00),(),(),2, 2, 0, 0,(),(),(d\x00S\x00),(),()}}{{{a=a,b=b}}}")
-        else:
-            expected = bytearray(b"{TestClass:__main__}[[[(<type \'object\'>, ()), [(<class \'__main__.TestClass\'>, (<type \'object\'>,))]]]]{{1, 1, 0, 0,({str:__builtin__}[[[(<type \'basestring\'>, (<type \'object\'>,)), [(<type \'str\'>, (<type \'basestring\'>,))]]]]{{}}{{{}}},{str:__builtin__}[[[(<type \'basestring\'>, (<type \'object\'>,)), [(<type \'str\'>, (<type \'basestring\'>,))]]]]{{}}{{{}}}),({str:__builtin__}[[[(<type \'basestring\'>, (<type \'object\'>,)), [(<type \'str\'>, (<type \'basestring\'>,))]]]]{{}}{{{}}},{str:__builtin__}[[[(<type \'basestring\'>, (<type \'object\'>,)), [(<type \'str\'>, (<type \'basestring\'>,))]]]]{{}}{{{}}}),(d\x01\x00|\x00\x00_\x00\x00d\x02\x00|\x00\x00_\x01\x00d\x00\x00S),(),(),2, 2, 0, 0,(),(),(d\x00\x00S),(),()}}{{{a=a,b=b}}}")
+        expected = {
+            (2,7): bytearray(b"{TestClass:__main__}[[[(<type \'object\'>, ()), [(<class \'__main__.TestClass\'>, (<type \'object\'>,))]]]]{{1, 1, 0, 0,(N.,a,b),(a,b),(d\x01\x00|\x00\x00_\x00\x00d\x02\x00|\x00\x00_\x01\x00d\x00\x00S),(),(),2, 2, 0, 0,(N.),(),(d\x00\x00S),(),()}}{{{a=a,b=b}}}"),
+            (3,5): bytearray(b"{TestClass:__main__}[[[(<class \'object\'>, ()), [(<class \'__main__.TestClass\'>, (<class \'object\'>,))]]]]{{1, 1, 0, 0,(N.,a,b),(a,b),(d\x01\x00|\x00\x00_\x00\x00d\x02\x00|\x00\x00_\x01\x00d\x00\x00S),(),(),2, 2, 0, 0,(N.),(),(d\x00\x00S),(),()}}{{{a=a,b=b}}}"),
+            (3,6): bytearray(b"{TestClass:__main__}[[[(<class \'object\'>, ()), [(<class \'__main__.TestClass\'>, (<class \'object\'>,))]]]]{{1, 1, 0, 0,(N.,a,b),(a,b),(d\x01|\x00_\x00d\x02|\x00_\x01d\x00S\x00),(),(),2, 2, 0, 0,(N.),(),(d\x00S\x00),(),()}}{{{a=a,b=b}}}"),
+        }
 
-        assert c == expected, "Got\n"+repr(c)+"\nExpected \n"+"\n"+repr(expected)
+        assert c == expected[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected \n"+"\n"+repr(expected[sys.version_info[:2]])
 
     def test_code_contents(self):
         """Test that Action._code_contents works"""
 
         code = compile("print('Hello, World!')", '<string>', 'exec')
         c = SCons.Action._code_contents(code)
-        if TestCmd.IS_PY3:
-            if TestCmd.IS_WINDOWS:
-                expected = [b'0, 0, 0, 0,(N.),(X\x05\x00\x00\x00printq\x00.),(e\x00d\x00\x83\x01\x01\x00d\x01S\x00)',
-                            b'0, 0, 0, 0,(N.),(X\x05\x00\x00\x00printq\x00.),(e\x00\x00d\x00\x00\x83\x01\x00\x01d\x01\x00S)'
-                            ]
-            else:
-                expected = [b'0, 0, 0, 0,(N.),(X\x05\x00\x00\x00printq\x00.),(e\x00\x00d\x00\x00\x83\x01\x00\x01d\x01\x00S)']
-        else:
-            expected = [b"0, 0, 0, 0,(N.),(),(d\x00\x00GHd\x01\x00S)"]
-        assert c in expected, "Got\n"+repr(c)+"\nExpected one of \n"+"\n".join([repr(e) for e in expected])
+
+        # Since the python bytecode has per version differences, we need different expected results per version
+        expected = {
+            (2,7) : bytearray(b'0, 0, 0, 0,(Hello, World!,N.),(),(d\x00\x00GHd\x01\x00S)'),
+            (3,5) : bytearray(b'0, 0, 0, 0,(Hello, World!,N.),(print),(e\x00\x00d\x00\x00\x83\x01\x00\x01d\x01\x00S)'),
+            (3,6) : bytearray(b'0, 0, 0, 0,(Hello, World!,N.),(print),(e\x00d\x00\x83\x01\x01\x00d\x01S\x00)'),
+        }
+
+        assert c == expected[sys.version_info[:2]], "Got\n"+repr(c)+"\nExpected \n"+"\n"+expected[sys.version_info[:2]]
+
 
 
 if __name__ == "__main__":
@@ -2137,8 +2145,10 @@ if __name__ == "__main__":
         names = unittest.getTestCaseNames(tclass, 'test_')
         suite.addTests(list(map(tclass, names)))
 
-    # TestUnit.run(suite)
-    unittest.main()
+    TestUnit.run(suite)
+
+    # Swap this for above to debug otherwise you can't run individual tests as TestUnit is swallowing arguments
+    # unittest.main()
 
 # Local Variables:
 # tab-width:4