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(loader, tests, ignore, example)
42
43
44class TestExample(fake_filesystem_unittest.TestCase):  # pylint: disable=R0904
45    """Test the example module.
46    The os and shutil modules have been replaced with the fake modules,
47    so that all of the calls to os and shutil in the tested example code
48    occur in the fake filesystem.
49    """
50
51    def setUp(self):
52        """Invoke the :py:class:`pyfakefs.fake_filesystem_unittest.TestCase`
53        `self.setUp()` method.  This defines:
54
55        * Attribute `self.fs`, an instance of
56          :py:class:`pyfakefs.fake_filesystem.FakeFilesystem`. This is useful
57          for creating test files.
58        * Attribute `self.stubs`, an instance of
59          :py:class:`pyfakefs.mox3_stubout.StubOutForTesting`. Use this if
60          you need to define additional stubs.
61        """
62
63        # This is before setUpPyfakefs(), so still using the real file system
64        self.filepath = os.path.realpath(__file__)
65        with io.open(self.filepath, "rb") as f:
66            self.real_contents = f.read()
67
68        self.setUpPyfakefs()
69
70    def tearDown(self):
71        # No longer need self.tearDownPyfakefs()
72        pass
73
74    def test_create_file(self):
75        """Test example.create_file() which uses `open()`
76        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", contents="First line\n" "Second Line\n")
89        self.assertTrue(os.path.exists("/test/full.txt"))
90        example.delete_file("/test/full.txt")
91        self.assertFalse(os.path.exists("/test/full.txt"))
92
93    def test_file_exists(self):
94        """Test example.path_exists() which uses `os.path.exists()`."""
95        self.assertFalse(example.path_exists("/test/empty.txt"))
96        self.fs.create_file("/test/empty.txt")
97        self.assertTrue(example.path_exists("/test/empty.txt"))
98
99    def test_get_globs(self):
100        """Test example.get_glob()."""
101        self.assertFalse(os.path.isdir("/test"))
102        self.fs.create_dir("/test/dir1/dir2a")
103        self.assertTrue(os.path.isdir("/test/dir1/dir2a"))
104        # os.mkdirs() works, too.
105        os.makedirs("/test/dir1/dir2b")
106        self.assertTrue(os.path.isdir("/test/dir1/dir2b"))
107
108        self.assertEqual(example.get_glob("/test/dir1/nonexistent*"), [])
109        is_windows = sys.platform.startswith("win")
110        matching_paths = sorted(example.get_glob("/test/dir1/dir*"))
111        if is_windows:
112            self.assertEqual(matching_paths, [r"/test/dir1\dir2a", r"/test/dir1\dir2b"])
113        else:
114            self.assertEqual(matching_paths, ["/test/dir1/dir2a", "/test/dir1/dir2b"])
115
116    def test_rm_tree(self):
117        """Test example.rm_tree() using `shutil.rmtree()`."""
118        self.fs.create_dir("/test/dir1/dir2a")
119        # os.mkdirs() works, too.
120        os.makedirs("/test/dir1/dir2b")
121        self.assertTrue(os.path.isdir("/test/dir1/dir2b"))
122        self.assertTrue(os.path.isdir("/test/dir1/dir2a"))
123
124        example.rm_tree("/test/dir1")
125        self.assertFalse(os.path.exists("/test/dir1"))
126
127    def test_os_scandir(self):
128        """Test example.scandir() which uses `os.scandir()`.
129
130        The os module has been replaced with the fake os module so the
131        fake filesystem path entries are returned instead of `os.DirEntry`
132        objects.
133        """
134        self.fs.create_file("/test/text.txt")
135        self.fs.create_dir("/test/dir")
136        self.fs.create_file("/linktest/linked")
137        self.fs.create_symlink("/test/linked_file", "/linktest/linked")
138
139        entries = sorted(example.scan_dir("/test"), key=lambda e: e.name)
140        self.assertEqual(3, len(entries))
141        self.assertEqual("linked_file", entries[1].name)
142        self.assertTrue(entries[0].is_dir())
143        self.assertTrue(entries[1].is_symlink())
144        self.assertTrue(entries[2].is_file())
145
146    @unittest.skipIf(
147        not use_scandir_package, "Testing only if scandir module is installed"
148    )
149    def test_scandir_scandir(self):
150        """Test example.scandir() which uses `scandir.scandir()`.
151
152        The scandir module has been replaced with the fake_scandir module so
153        the fake filesystem path entries are returned instead of
154        `scandir.DirEntry` objects.
155        """
156        self.fs.create_file("/test/text.txt")
157        self.fs.create_dir("/test/dir")
158
159        entries = sorted(example.scan_dir("/test"), key=lambda e: e.name)
160        self.assertEqual(2, len(entries))
161        self.assertEqual("text.txt", entries[1].name)
162        self.assertTrue(entries[0].is_dir())
163        self.assertTrue(entries[1].is_file())
164
165    def test_real_file_access(self):
166        """Test `example.file_contents()` for a real file after adding it using
167        `add_real_file()`."""
168        with self.assertRaises(OSError):
169            example.file_contents(self.filepath)
170        self.fs.add_real_file(self.filepath)
171        self.assertEqual(example.file_contents(self.filepath), self.real_contents)
172
173
174if __name__ == "__main__":
175    unittest.main()
176