1# -*- coding: utf-8 -*-
2#  Copyright 2011 Takeshi KOMIYA
3#
4#  Licensed under the Apache License, Version 2.0 (the "License");
5#  you may not use this file except in compliance with the License.
6#  You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10#  Unless required by applicable law or agreed to in writing, software
11#  distributed under the License is distributed on an "AS IS" BASIS,
12#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13#  See the License for the specific language governing permissions and
14#  limitations under the License.
15
16import os
17import re
18import sys
19import unittest
20
21from nose.tools import nottest
22
23import blockdiag
24import blockdiag.command
25from blockdiag.tests.utils import (TemporaryDirectory, capture_stderr,
26                                   supported_pdf, supported_pil)
27
28TESTDIR = os.path.dirname(__file__)
29FONTPATH = os.path.join(TESTDIR, 'VLGothic', 'VL-Gothic-Regular.ttf')
30
31
32def get_fontpath(testdir):
33    return os.path.join(testdir, 'VLGothic', 'VL-Gothic-Regular.ttf')
34
35
36def get_diagram_files(testdir):
37    diagramsdir = os.path.join(testdir, 'diagrams')
38
39    skipped = ['README', 'debian-logo-256color-palettealpha.png',
40               'errors', 'white.gif']
41    for file in os.listdir(diagramsdir):
42        if file in skipped:
43            pass
44        else:
45            yield os.path.join(diagramsdir, file)
46
47
48def test_generate():
49    mainfunc = blockdiag.command.main
50    basepath = os.path.dirname(__file__)
51    files = get_diagram_files(basepath)
52    options = []
53
54    for testcase in testcase_generator(basepath, mainfunc, files, options):
55        yield testcase
56
57
58def test_generate_with_separate():
59    mainfunc = blockdiag.command.main
60    basepath = os.path.dirname(__file__)
61    files = get_diagram_files(basepath)
62    filtered = (f for f in files if re.search('separate', f))
63    options = ['--separate']
64
65    for testcase in testcase_generator(basepath, mainfunc, filtered, options):
66        yield testcase
67
68
69@nottest
70def testcase_generator(basepath, mainfunc, files, options):
71    fontpath = get_fontpath(basepath)
72    options = options + ['-f', fontpath]
73
74    for source in files:
75        yield generate, mainfunc, 'svg', source, options
76
77        if not supported_pil():
78            yield unittest.skip("Pillow is not available")(generate)
79            yield unittest.skip("Pillow is not available")(generate)
80        elif os.environ.get('ALL_TESTS') is None:
81            message = "Skipped by default. To enable it, specify $ALL_TESTS=1"
82            yield unittest.skip(message)(generate)
83            yield unittest.skip(message)(generate)
84        else:
85            yield generate, mainfunc, 'png', source, options
86            yield generate, mainfunc, 'png', source, options + ['--antialias']
87
88        if not supported_pdf():
89            yield unittest.skip("reportlab is not available")(generate)
90        elif os.environ.get('ALL_TESTS') is None:
91            message = "Skipped by default. To enable it, specify $ALL_TESTS=1"
92            yield unittest.skip(message)(generate)
93        else:
94            yield generate, mainfunc, 'pdf', source, options
95
96
97@capture_stderr
98def generate(mainfunc, filetype, source, options):
99    try:
100        tmpdir = TemporaryDirectory()
101        fd, tmpfile = tmpdir.mkstemp()
102        os.close(fd)
103
104        mainfunc(['--debug', '-T', filetype, '-o', tmpfile, source] +
105                 list(options))
106    finally:
107        tmpdir.clean()
108
109
110def not_exist_font_config_option_test():
111    args = ['-f', '/font_is_not_exist', '-f', FONTPATH, 'input.diag']
112    options = blockdiag.command.BlockdiagOptions(blockdiag).parse(args)
113
114    from blockdiag.utils.bootstrap import detectfont
115    detectfont(options)
116
117
118def stdin_test():
119    testdir = os.path.dirname(__file__)
120    diagpath = os.path.join(testdir, 'diagrams', 'single_edge.diag')
121
122    try:
123        stdin = sys.stdin
124        sys.stdin = open(diagpath, 'r')
125
126        tmpdir = TemporaryDirectory()
127        fd, tmpfile = tmpdir.mkstemp()
128        os.close(fd)
129
130        args = ['-T', 'SVG', '-o', tmpfile, '-']
131        ret = blockdiag.command.main(args)
132        assert ret == 0
133    finally:
134        sys.stdin = stdin
135        tmpdir.clean()
136
137
138@capture_stderr
139def ghostscript_not_found_test():
140    testdir = os.path.dirname(__file__)
141    diagpath = os.path.join(testdir, 'diagrams', 'background_url_image.diag')
142
143    try:
144        old_path = os.environ['PATH']
145        os.environ['PATH'] = ''
146        tmpdir = TemporaryDirectory()
147        fd, tmpfile = tmpdir.mkstemp()
148        os.close(fd)
149
150        args = ['-T', 'SVG', '-o', tmpfile, diagpath]
151        ret = blockdiag.command.main(args)
152        assert 'Could not convert image:' in sys.stderr.getvalue()
153        assert ret == 0
154    finally:
155        tmpdir.clean()
156        os.environ['PATH'] = old_path
157
158
159@capture_stderr
160def svg_includes_source_code_tag_test():
161    from xml.etree import ElementTree
162
163    testdir = os.path.dirname(__file__)
164    diagpath = os.path.join(testdir, 'diagrams', 'single_edge.diag')
165
166    try:
167        tmpdir = TemporaryDirectory()
168        fd, tmpfile = tmpdir.mkstemp()
169        os.close(fd)
170
171        args = ['-T', 'SVG', '-o', tmpfile, diagpath]
172        blockdiag.command.main(args)
173
174        # compare embeded source code
175        source_code = open(diagpath).read()
176        tree = ElementTree.parse(tmpfile)
177        desc = tree.find('{http://www.w3.org/2000/svg}desc')
178
179        # strip spaces
180        source_code = re.sub(r'\s+', ' ', source_code)
181        embeded = re.sub(r'\s+', ' ', desc.text)
182        assert source_code == embeded
183    finally:
184        tmpdir.clean()
185