12fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#!/usr/bin/env python
22fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# Copyright (C) 2010 Google Inc. All rights reserved.
32fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#
42fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# Redistribution and use in source and binary forms, with or without
52fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# modification, are permitted provided that the following conditions
62fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# are met:
72fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#
82fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# 1.  Redistributions of source code must retain the above copyright
92fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#     notice, this list of conditions and the following disclaimer.
102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# 2.  Redistributions in binary form must reproduce the above copyright
112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#     notice, this list of conditions and the following disclaimer in the
122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#     documentation and/or other materials provided with the distribution.
132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#
142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochimport os
262fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockimport re
2781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochimport sys
282fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockimport testoutput
292fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockimport unittest
302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
322fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockclass FakeFile(object):
332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def __init__(self, filename, contents="fake contents"):
342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._filename = filename
352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._contents = contents
362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def name(self):
382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return self._filename
392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def contents(self):
412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return self._contents
422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
442fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockclass FakeTestOutput(testoutput.TestOutput):
452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def __init__(self, platform, output_type, contents, is_expected=False):
462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._output_type = output_type
472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._contents = contents
482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._is_expected = is_expected
492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        actual = 'actual'
502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if is_expected:
512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            actual = 'expected'
522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        test_name = 'anonymous-test-%s.txt' % actual
532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        file = FakeFile(test_name, contents)
542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        super(FakeTestOutput, self).__init__(platform, output_type, [file])
552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def contents(self):
572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return self._contents
582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def retarget(self, platform):
602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return FakeTestOutput(platform, self._output_type, self._contents, self._is_expected)
612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
632fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockclass TestOutputTest(unittest.TestCase):
642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def _check_name(self, filename, expected_test_name):
6581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        # FIXME: should consider using MockFileSystem here so as to not
6681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        # have to worry about platform-specific path separators.
6781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if sys.platform == 'win32':
6881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            filename = filename.replace('/', os.path.sep)
6981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            expected_test_name = expected_test_name.replace('/', os.path.sep)
702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        r = testoutput.TextTestOutput(None, FakeFile(filename))
712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self.assertEquals(expected_test_name, r.name())
722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def _check_platform(self, filename, expected_platform):
7481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        # FIXME: should consider using MockFileSystem here so as to not
7581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        # have to worry about platform-specific path separators.
7681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if sys.platform == 'win32':
7781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            filename = filename.replace('/', os.path.sep)
782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        r = testoutput.TextTestOutput(None, FakeFile(filename))
792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self.assertEquals(expected_platform, r.platform())
802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def test_extracts_name_correctly(self):
822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._check_name('LayoutTests/fast/dom/a-expected.txt', 'fast/dom/a')
832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._check_name('LayoutTests/fast/dom/a-actual.txt', 'fast/dom/a')
842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._check_name('LayoutTests/platform/win/fast/a-expected.txt', 'fast/a')
852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._check_name('LayoutTests/platform/win/fast/a-expected.checksum', 'fast/a')
862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._check_name('fast/dom/test-expected.txt', 'fast/dom/test')
872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._check_name('layout-test-results/fast/a-actual.checksum', 'fast/a')
882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def test_extracts_platform_correctly(self):
902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._check_platform('LayoutTests/platform/win/fast/a-expected.txt', 'win')
912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._check_platform('platform/win/fast/a-expected.txt', 'win')
922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._check_platform('platform/mac/fast/a-expected.txt', 'mac')
932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self._check_platform('fast/a-expected.txt', None)
942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def test_outputs_from_an_actual_file_are_marked_as_such(self):
962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        r = testoutput.TextTestOutput(None, FakeFile('test-actual.txt'))
972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self.assertTrue(r.is_actual())
982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def test_outputs_from_an_expected_file_are_not_actual(self):
1002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        r = testoutput.TextTestOutput(None, FakeFile('test-expected.txt'))
1012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self.assertFalse(r.is_actual())
1022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def test_is_new_baseline_for(self):
1042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        expected = testoutput.TextTestOutput('mac', FakeFile('test-expected.txt'))
1052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        actual = testoutput.TextTestOutput('mac', FakeFile('test-actual.txt'))
1062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self.assertTrue(actual.is_new_baseline_for(expected))
1072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self.assertFalse(expected.is_new_baseline_for(actual))
1082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def test__eq__(self):
1102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        r1 = testoutput.TextTestOutput('mac', FakeFile('test-expected.txt', 'contents'))
1112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        r2 = testoutput.TextTestOutput('mac', FakeFile('test-expected.txt', 'contents'))
1122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        r3 = testoutput.TextTestOutput('win', FakeFile('test-expected.txt', 'contents'))
1132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self.assertEquals(r1, r2)
1152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self.assertEquals(r1, r2.retarget('mac'))
1162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self.assertNotEquals(r1, r2.retarget('win'))
1172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def test__hash__(self):
1192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        r1 = testoutput.TextTestOutput('mac', FakeFile('test-expected.txt', 'contents'))
1202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        r2 = testoutput.TextTestOutput('mac', FakeFile('test-expected.txt', 'contents'))
1212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        r3 = testoutput.TextTestOutput(None, FakeFile('test-expected.txt', None))
1222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        x = set([r1, r2])
1242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self.assertEquals(1, len(set([r1, r2])))
1252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self.assertEquals(2, len(set([r1, r2, r3])))
1262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def test_image_diff_is_invoked_for_image_outputs_without_checksum(self):
1282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        r1 = testoutput.ImageTestOutput('mac', FakeFile('test-expected.png', 'asdf'), FakeFile('test-expected.checksum', 'check'))
1292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        r2 = testoutput.ImageTestOutput('mac', FakeFile('test-expected.png', 'asdf'), None)
1302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        # Default behaviour is to just compare on image contents.
1322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self.assertTrue(r1.same_content(r2))
1332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        class AllImagesAreDifferent(object):
1352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            def same_image(self, image1, image2):
1362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                return False
1372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        # But we can install other image differs.
1392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        testoutput.ImageTestOutput.image_differ = AllImagesAreDifferent()
1402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self.assertFalse(r1.same_content(r2))
1422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1432fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockif __name__ == "__main__":
1442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    unittest.main()
145