1# Copyright 2014 Altera Corporation. All Rights Reserved.
2# Author: John McGehee
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
16"""
17Test the :py:class`pyfakefs.example` module to demonstrate the usage of the
18:py:class`pyfakefs.fake_filesystem_unittest.TestCase` base class.
19
20Fake filesystem functions like `create_file()`, `create_dir()` or
21`create_symlink()` are often used to set up file structures at the beginning
22of a test.
23While you could also use the familiar `open()`, `os.mkdirs()` and similar
24functions, these functions can make the test code shorter and more readable.
25`create_file()` is particularly convenient because it creates all parent
26directories and allows you to specify the contents or the size of the file.
27"""
28
29import io
30import os
31import sys
32import unittest
33
34from pyfakefs import fake_filesystem_unittest
35from pyfakefs.extra_packages import use_scandir_package
36from pyfakefs.tests import example  # The module under test
37
38
39def load_tests(loader, tests, ignore):
40    """Load the pyfakefs/example.py doctest tests into unittest."""
41    return fake_filesystem_unittest.load_doctests(
42        loader, tests, ignore, example)
43
44
45class TestExample(fake_filesystem_unittest.TestCase):  # pylint: disable=R0904
46    """Test the example module.
47       The os and shutil modules have been replaced with the fake modules,
48       so that all of the calls to os and shutil in the tested example code
49       occur in the fake filesystem.
50    """
51
52    def setUp(self):
53        """Invoke the :py:class:`pyfakefs.fake_filesystem_unittest.TestCase`
54        `self.setUp()` method.  This defines:
55
56        * Attribute `self.fs`, an instance of
57          :py:class:`pyfakefs.fake_filesystem.FakeFilesystem`. This is useful
58          for creating test files.
59        * Attribute `self.stubs`, an instance of
60          :py:class:`pyfakefs.mox3_stubout.StubOutForTesting`. Use this if
61          you need to define additional stubs.
62        """
63
64        # This is before setUpPyfakefs(), so still using the real file system
65        self.filepath = os.path.realpath(__file__)
66        with io.open(self.filepath, 'rb') as f:
67            self.real_contents = f.read()
68
69        self.setUpPyfakefs()
70
71    def tearDown(self):
72        # No longer need self.tearDownPyfakefs()
73        pass
74
75    def test_create_file(self):
76        """Test example.create_file() which uses `open()` and `file.write()`.
77        """
78        self.assertFalse(os.path.isdir('/test'))
79        os.mkdir('/test')
80        self.assertTrue(os.path.isdir('/test'))
81
82        self.assertFalse(os.path.exists('/test/file.txt'))
83        example.create_file('/test/file.txt')
84        self.assertTrue(os.path.exists('/test/file.txt'))
85
86    def test_delete_file(self):
87        """Test example.delete_file() which uses `os.remove()`."""
88        self.fs.create_file('/test/full.txt',
89                            contents='First line\n'
90                                     'Second Line\n')
91        self.assertTrue(os.path.exists('/test/full.txt'))
92        example.delete_file('/test/full.txt')
93        self.assertFalse(os.path.exists('/test/full.txt'))
94
95    def test_file_exists(self):
96        """Test example.path_exists() which uses `os.path.exists()`."""
97        self.assertFalse(example.path_exists('/test/empty.txt'))
98        self.fs.create_file('/test/empty.txt')
99        self.assertTrue(example.path_exists('/test/empty.txt'))
100
101    def test_get_globs(self):
102        """Test example.get_glob()."""
103        self.assertFalse(os.path.isdir('/test'))
104        self.fs.create_dir('/test/dir1/dir2a')
105        self.assertTrue(os.path.isdir('/test/dir1/dir2a'))
106        # os.mkdirs() works, too.
107        os.makedirs('/test/dir1/dir2b')
108        self.assertTrue(os.path.isdir('/test/dir1/dir2b'))
109
110        self.assertEqual(example.get_glob('/test/dir1/nonexistent*'),
111                         [])
112        is_windows = sys.platform.startswith('win')
113        matching_paths = sorted(example.get_glob('/test/dir1/dir*'))
114        if is_windows:
115            self.assertEqual(matching_paths,
116                             [r'\test\dir1\dir2a', r'\test\dir1\dir2b'])
117        else:
118            self.assertEqual(matching_paths,
119                             ['/test/dir1/dir2a', '/test/dir1/dir2b'])
120
121    def test_rm_tree(self):
122        """Test example.rm_tree() using `shutil.rmtree()`."""
123        self.fs.create_dir('/test/dir1/dir2a')
124        # os.mkdirs() works, too.
125        os.makedirs('/test/dir1/dir2b')
126        self.assertTrue(os.path.isdir('/test/dir1/dir2b'))
127        self.assertTrue(os.path.isdir('/test/dir1/dir2a'))
128
129        example.rm_tree('/test/dir1')
130        self.assertFalse(os.path.exists('/test/dir1'))
131
132    def test_os_scandir(self):
133        """Test example.scandir() which uses `os.scandir()`.
134
135        The os module has been replaced with the fake os module so the
136        fake filesystem path entries are returned instead of `os.DirEntry`
137        objects.
138        """
139        self.fs.create_file('/test/text.txt')
140        self.fs.create_dir('/test/dir')
141        self.fs.create_file('/linktest/linked')
142        self.fs.create_symlink('/test/linked_file', '/linktest/linked')
143
144        entries = sorted(example.scan_dir('/test'), key=lambda e: e.name)
145        self.assertEqual(3, len(entries))
146        self.assertEqual('linked_file', entries[1].name)
147        self.assertTrue(entries[0].is_dir())
148        self.assertTrue(entries[1].is_symlink())
149        self.assertTrue(entries[2].is_file())
150
151    @unittest.skipIf(not use_scandir_package,
152                     'Testing only if scandir module is installed')
153    def test_scandir_scandir(self):
154        """Test example.scandir() which uses `scandir.scandir()`.
155
156        The scandir module has been replaced with the fake_scandir module so
157        the fake filesystem path entries are returned instead of
158        `scandir.DirEntry` objects.
159        """
160        self.fs.create_file('/test/text.txt')
161        self.fs.create_dir('/test/dir')
162
163        entries = sorted(example.scan_dir('/test'), key=lambda e: e.name)
164        self.assertEqual(2, len(entries))
165        self.assertEqual('text.txt', entries[1].name)
166        self.assertTrue(entries[0].is_dir())
167        self.assertTrue(entries[1].is_file())
168
169    def test_real_file_access(self):
170        """Test `example.file_contents()` for a real file after adding it using
171         `add_real_file()`."""
172        with self.assertRaises(OSError):
173            example.file_contents(self.filepath)
174        self.fs.add_real_file(self.filepath)
175        self.assertEqual(example.file_contents(self.filepath),
176                         self.real_contents)
177
178
179if __name__ == "__main__":
180    unittest.main()
181