• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zopefoundation / z3c.rml / 16098868126

14 Apr 2025 06:50AM UTC coverage: 87.385%. Remained the same
16098868126

push

github

icemac
Back to development: 5.1

561 of 792 branches covered (70.83%)

Branch coverage included in aggregate %.

3990 of 4416 relevant lines covered (90.35%)

0.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

54.78
/src/z3c/rml/tests/test_rml.py
1
##############################################################################
2
#
3
# Copyright (c) 2007 Zope Foundation and Contributors.
4
# All Rights Reserved.
5
#
6
# This software is subject to the provisions of the Zope Public License,
7
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
8
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
9
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
11
# FOR A PARTLAR PURPOSE.
12
#
13
##############################################################################
14
"""Testing all XML Locale functionality.
15
"""
16
import base64
1✔
17
import logging
1✔
18
import os
1✔
19
import subprocess
1✔
20
import sys
1✔
21
import tempfile
1✔
22
import unittest
1✔
23

24
from PIL import Image
1✔
25
from PIL import ImageChops
1✔
26

27
import z3c.rml.tests
1✔
28
from z3c.rml import rml2pdf
1✔
29

30

31
LOG_FILE = os.path.join(os.path.dirname(__file__), 'render.log')
1✔
32

33

34
def gs_command(path):
1✔
35
    return ('gs', '-q', '-sNOPAUSE', '-sDEVICE=png256',
×
36
            '-sOutputFile=%s[Page-%%d].png' % path[:-4],
37
            path, '-c', 'quit')
38

39

40
class RMLRenderingTestCase(unittest.TestCase):
1✔
41

42
    def __init__(self, inPath, outPath):
1✔
43
        self._inPath = inPath
1✔
44
        self._outPath = outPath
1✔
45
        unittest.TestCase.__init__(self)
1✔
46

47
    def setUp(self):
1✔
48
        import z3c.rml.tests.module
1✔
49
        sys.modules['module'] = z3c.rml.tests.module
1✔
50
        sys.modules['mymodule'] = z3c.rml.tests.module
1✔
51

52
    def tearDown(self):
1✔
53
        del sys.modules['module']
1✔
54
        del sys.modules['mymodule']
1✔
55

56
        from z3c.rml.document import LOGGER_NAME
1✔
57
        for handler in logging.getLogger(LOGGER_NAME).handlers:
1✔
58
            if handler.baseFilename == LOG_FILE:
1!
59
                handler.close()
1✔
60

61
        if os.path.exists(LOG_FILE):
1✔
62
            os.remove(LOG_FILE)
1✔
63

64
    def runTest(self):
1✔
65
        rml2pdf.go(self._inPath, self._outPath)
1✔
66

67

68
class ComparePDFTestCase(unittest.TestCase):
1✔
69

70
    level = 2
1✔
71

72
    def __init__(self, basePath, testPath):
1✔
73
        self._basePath = basePath
1✔
74
        self._testPath = testPath
1✔
75
        unittest.TestCase.__init__(self)
1✔
76

77
    def assertSameImage(self, baseImage, testImage):
1✔
78
        base_file = open(baseImage, 'rb')
×
79
        test_file = open(testImage, 'rb')
×
80
        base_image = Image.open(base_file)
×
81
        base = base_image.getdata()
×
82
        test_image = Image.open(test_file)
×
83
        test = test_image.getdata()
×
84

85
        has_diff = True
×
86
        for i in range(len(base)):
×
87
            # Stop at first difference
88
            if (base[i] - test[i]) != 0:
×
89
                break
×
90
        else:
91
            has_diff = False
×
92

93
        if has_diff and 'SHOW_IMAGE_DIFF' in os.environ:
×
94
            test_image.show()
×
95
            base_image.show()
×
96
            differ = ImageChops.subtract(test_image, base_image)
×
97
            differ.show()
×
98
            differ2 = ImageChops.subtract(base_image, test_image)
×
99
            differ2.show()
×
100
            # output the result as base64 for travis debugging
101
            if 'SHOW_DIFF_DEBUG' in os.environ:
×
102
                print(base64.b64encode(differ.tobytes()))
×
103
                print(base64.b64encode(differ2.tobytes()))
×
104

105
        if has_diff and 'SHOW_DIFF_DEBUG' in os.environ:
×
106
            print()
×
107
            print(os.system("gs --version"))
×
108

109
            base_file.seek(0)
×
110
            print(baseImage)
×
111
            print(base64.b64encode(base_file.read()))
×
112
            print(self._basePath)
×
113
            with open(self._basePath, 'rb') as base_pdf:
×
114
                print(base64.b64encode(base_pdf.read()))
×
115

116
            test_file.seek(0)
×
117
            print(testImage)
×
118
            print(base64.b64encode(test_file.read()))
×
119
            print(self._testPath)
×
120
            with open(self._testPath, 'rb') as test_pdf:
×
121
                print(base64.b64encode(test_pdf.read()))
×
122

123
        base_file.close()
×
124
        test_file.close()
×
125

126
        if has_diff:
×
127
            self.fail(
128
                'Image is not the same: %s' % os.path.basename(baseImage))
129

130
    def runTest(self):
1✔
131
        # Convert the base PDF to image(s)
132
        status = subprocess.Popen(gs_command(self._basePath)).wait()
×
133
        if status:
×
134
            return
×
135
        # Convert the test PDF to image(s)
136
        status = subprocess.Popen(gs_command(self._testPath)).wait()
×
137
        if status:
×
138
            return
×
139
        # Go through all pages and ensure their equality
140
        n = 1
×
141
        while True:
×
142
            baseImage = self._basePath[:-4] + '[Page-%i].png' % n
×
143
            testImage = self._testPath[:-4] + '[Page-%i].png' % n
×
144
            if os.path.exists(baseImage) and os.path.exists(testImage):
×
145
                self.assertSameImage(baseImage, testImage)
×
146
            else:
147
                break
×
148
            n += 1
×
149

150

151
class CompareFileTestCase(unittest.TestCase):
1✔
152

153
    def __init__(self, testPath, contains):
1✔
154
        self._testPath = testPath
1✔
155
        self._contains = contains
1✔
156
        unittest.TestCase.__init__(self)
1✔
157

158
    def runTest(self):
1✔
159
        with open(self._testPath, 'rb') as io:
1✔
160
            contents = io.read()
1✔
161

162
            if self._contains not in contents:
1✔
163
                self.fail(
164
                    'PDF file does not contain: %s' % self._contains
165
                )
166

167

168
def test_suite():
1✔
169
    if False:
1✔
170
        # Debug info
171
        import pkg_resources
172
        print("Environment\n===========")
173
        print("reportlab:")
174
        print(pkg_resources.get_distribution('reportlab').version)
175
        print("ghostscript:")
176
        os.system("gs --version")
177

178
    suite = unittest.TestSuite()
1✔
179
    here = os.path.dirname(z3c.rml.tests.__file__)
1✔
180
    inputDir = os.path.join(here, 'input')
1✔
181
    outputDir = tempfile.mkdtemp('z3c.rml-output')
1✔
182
    print(f'output dir: {outputDir}')
1✔
183
    expectDir = os.path.join(here, 'expected')
1✔
184
    for filename in os.listdir(inputDir):
1✔
185
        if not filename.endswith(".rml"):
1✔
186
            continue
1✔
187

188
        inPath = os.path.join(inputDir, filename)
1✔
189
        outPath = os.path.join(outputDir, filename[:-4] + '.pdf')
1✔
190
        expectPath = os.path.join(expectDir, filename[:-4] + '.pdf')
1✔
191

192
        # ** Test RML to PDF rendering **
193
        # Create new type, so that we can get test matching
194
        TestCase = type(filename[:-4], (RMLRenderingTestCase,), {})
1✔
195
        case = TestCase(inPath, outPath)
1✔
196
        suite.addTest(case)
1✔
197
        # ** Test PDF rendering correctness **
198
        TestCase = type('compare-' + filename[:-4], (ComparePDFTestCase,), {})
1✔
199
        case = TestCase(expectPath, outPath)
1✔
200
        suite.addTest(case)
1✔
201

202
        if filename == 'printScaling.rml':
1✔
203
            TestCase = type('compare-file-' + filename[:-4],
1✔
204
                            (CompareFileTestCase,), {})
205
            case = TestCase(outPath, b'/PrintScaling /None')
1✔
206
            suite.addTest(case)
1✔
207

208
    return suite
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc