~bzr-pqm/bzr/bzr.dev

5557.1.15 by John Arbash Meinel
Merge bzr.dev 5597 to resolve NEWS, aka bzr-2.3.txt
1
# Copyright (C) 2006-2011 Canonical Ltd
1836.1.13 by John Arbash Meinel
Adding functions for getting user ignores.
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1836.1.13 by John Arbash Meinel
Adding functions for getting user ignores.
16
17
"""Tests for handling of ignore files"""
18
19
from cStringIO import StringIO
20
5579.3.1 by Jelmer Vernooij
Remove unused imports.
21
from bzrlib import (
22
    config,
23
    ignores,
24
    )
25
from bzrlib.tests import (
26
    TestCase,
27
    TestCaseInTempDir,
28
    TestCaseWithTransport,
29
    )
1836.1.13 by John Arbash Meinel
Adding functions for getting user ignores.
30
31
32
class TestParseIgnoreFile(TestCase):
33
34
    def test_parse_fancy(self):
35
        ignored = ignores.parse_ignore_file(StringIO(
36
                './rootdir\n'
37
                'randomfile*\n'
38
                'path/from/ro?t\n'
39
                'unicode\xc2\xb5\n' # u'\xb5'.encode('utf8')
40
                'dos\r\n'
41
                '\n' # empty line
42
                '#comment\n'
43
                ' xx \n' # whitespace
4948.5.4 by John Whitley
bzrlib.globbing.normalize_pattern needed fix to avoid mangling ignore
44
                '!RE:^\.z.*\n'
4948.5.6 by John Whitley
A trial implementation of '!!' syntax for double-negative ignore exclusions.
45
                '!!./.zcompdump\n'
1836.1.13 by John Arbash Meinel
Adding functions for getting user ignores.
46
                ))
1836.1.30 by John Arbash Meinel
Change ignore functions to use sets instead of lists.
47
        self.assertEqual(set(['./rootdir',
1836.1.25 by John Arbash Meinel
cleanups suggested by Martin.
48
                          'randomfile*',
49
                          'path/from/ro?t',
50
                          u'unicode\xb5',
51
                          'dos',
52
                          ' xx ',
4948.5.4 by John Whitley
bzrlib.globbing.normalize_pattern needed fix to avoid mangling ignore
53
                          '!RE:^\.z.*',
4948.5.6 by John Whitley
A trial implementation of '!!' syntax for double-negative ignore exclusions.
54
                          '!!./.zcompdump',
1836.1.30 by John Arbash Meinel
Change ignore functions to use sets instead of lists.
55
                         ]), ignored)
1836.1.25 by John Arbash Meinel
cleanups suggested by Martin.
56
1836.1.13 by John Arbash Meinel
Adding functions for getting user ignores.
57
    def test_parse_empty(self):
58
        ignored = ignores.parse_ignore_file(StringIO(''))
1836.1.30 by John Arbash Meinel
Change ignore functions to use sets instead of lists.
59
        self.assertEqual(set([]), ignored)
5119.1.4 by Jason Spashett
Add test for parsing non utf8
60
        
61
    def test_parse_non_utf8(self):
62
        """Lines with non utf 8 characters should be discarded."""
63
        ignored = ignores.parse_ignore_file(StringIO(
64
                'utf8filename_a\n'
65
                'invalid utf8\x80\n'
66
                'utf8filename_b\n'
67
                ))
68
        self.assertEqual(set([
69
                        'utf8filename_a',
70
                        'utf8filename_b',
71
                       ]), ignored)
1836.1.13 by John Arbash Meinel
Adding functions for getting user ignores.
72
73
1836.1.15 by John Arbash Meinel
Updated WorkingTree to use the new user-level ignores.
74
class TestUserIgnores(TestCaseInTempDir):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
75
1836.1.13 by John Arbash Meinel
Adding functions for getting user ignores.
76
    def test_create_if_missing(self):
77
        # $HOME should be set to '.'
78
        ignore_path = config.user_ignore_config_filename()
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
79
        self.assertPathDoesNotExist(ignore_path)
1836.1.13 by John Arbash Meinel
Adding functions for getting user ignores.
80
        user_ignores = ignores.get_user_ignores()
1836.1.30 by John Arbash Meinel
Change ignore functions to use sets instead of lists.
81
        self.assertEqual(set(ignores.USER_DEFAULTS), user_ignores)
1836.1.13 by John Arbash Meinel
Adding functions for getting user ignores.
82
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
83
        self.assertPathExists(ignore_path)
1836.1.13 by John Arbash Meinel
Adding functions for getting user ignores.
84
        f = open(ignore_path, 'rb')
85
        try:
86
            entries = ignores.parse_ignore_file(f)
87
        finally:
88
            f.close()
1836.1.30 by John Arbash Meinel
Change ignore functions to use sets instead of lists.
89
        self.assertEqual(set(ignores.USER_DEFAULTS), entries)
1836.1.13 by John Arbash Meinel
Adding functions for getting user ignores.
90
91
    def test_use_existing(self):
92
        patterns = ['*.o', '*.py[co]', u'\xe5*']
1836.1.31 by John Arbash Meinel
Make set_user_ignores a private function, and update the doc string to recommend it isn't used.
93
        ignores._set_user_ignores(patterns)
1836.1.13 by John Arbash Meinel
Adding functions for getting user ignores.
94
95
        user_ignores = ignores.get_user_ignores()
1836.1.30 by John Arbash Meinel
Change ignore functions to use sets instead of lists.
96
        self.assertEqual(set(patterns), user_ignores)
1836.1.14 by John Arbash Meinel
Adding a helper function that will only add patterns if they are missing.
97
98
    def test_use_empty(self):
1836.1.31 by John Arbash Meinel
Make set_user_ignores a private function, and update the doc string to recommend it isn't used.
99
        ignores._set_user_ignores([])
1836.1.14 by John Arbash Meinel
Adding a helper function that will only add patterns if they are missing.
100
        ignore_path = config.user_ignore_config_filename()
1836.1.15 by John Arbash Meinel
Updated WorkingTree to use the new user-level ignores.
101
        self.check_file_contents(ignore_path, '')
1836.1.14 by John Arbash Meinel
Adding a helper function that will only add patterns if they are missing.
102
1836.1.30 by John Arbash Meinel
Change ignore functions to use sets instead of lists.
103
        self.assertEqual(set([]), ignores.get_user_ignores())
1836.1.14 by John Arbash Meinel
Adding a helper function that will only add patterns if they are missing.
104
1836.1.15 by John Arbash Meinel
Updated WorkingTree to use the new user-level ignores.
105
    def test_set(self):
106
        patterns = ['*.py[co]', '*.py[oc]']
1836.1.31 by John Arbash Meinel
Make set_user_ignores a private function, and update the doc string to recommend it isn't used.
107
        ignores._set_user_ignores(patterns)
1836.1.15 by John Arbash Meinel
Updated WorkingTree to use the new user-level ignores.
108
1836.1.30 by John Arbash Meinel
Change ignore functions to use sets instead of lists.
109
        self.assertEqual(set(patterns), ignores.get_user_ignores())
1836.1.15 by John Arbash Meinel
Updated WorkingTree to use the new user-level ignores.
110
111
        patterns = ['vim', '*.swp']
1836.1.31 by John Arbash Meinel
Make set_user_ignores a private function, and update the doc string to recommend it isn't used.
112
        ignores._set_user_ignores(patterns)
1836.1.30 by John Arbash Meinel
Change ignore functions to use sets instead of lists.
113
        self.assertEqual(set(patterns), ignores.get_user_ignores())
1836.1.15 by John Arbash Meinel
Updated WorkingTree to use the new user-level ignores.
114
1836.1.14 by John Arbash Meinel
Adding a helper function that will only add patterns if they are missing.
115
    def test_add(self):
116
        """Test that adding will not duplicate ignores"""
117
        # Create an empty file
1836.1.31 by John Arbash Meinel
Make set_user_ignores a private function, and update the doc string to recommend it isn't used.
118
        ignores._set_user_ignores([])
1836.1.14 by John Arbash Meinel
Adding a helper function that will only add patterns if they are missing.
119
120
        patterns = ['foo', './bar', u'b\xe5z']
121
        added = ignores.add_unique_user_ignores(patterns)
122
        self.assertEqual(patterns, added)
1836.1.30 by John Arbash Meinel
Change ignore functions to use sets instead of lists.
123
        self.assertEqual(set(patterns), ignores.get_user_ignores())
1836.1.14 by John Arbash Meinel
Adding a helper function that will only add patterns if they are missing.
124
2077.1.2 by Kent Gibson
Strip trailing slashes from ignore patterns (#4559).
125
    def test_add_directory(self):
126
        """Test that adding a directory will strip any trailing slash"""
127
        # Create an empty file
128
        ignores._set_user_ignores([])
129
2298.8.3 by Kent Gibson
Extended test cases to test bug 86451.
130
        in_patterns = ['foo/', 'bar/', 'baz\\']
2077.1.2 by Kent Gibson
Strip trailing slashes from ignore patterns (#4559).
131
        added = ignores.add_unique_user_ignores(in_patterns)
2298.8.3 by Kent Gibson
Extended test cases to test bug 86451.
132
        out_patterns = [ x.rstrip('/\\') for x in in_patterns ]
2077.1.2 by Kent Gibson
Strip trailing slashes from ignore patterns (#4559).
133
        self.assertEqual(out_patterns, added)
134
        self.assertEqual(set(out_patterns), ignores.get_user_ignores())
135
1836.1.14 by John Arbash Meinel
Adding a helper function that will only add patterns if they are missing.
136
    def test_add_unique(self):
137
        """Test that adding will not duplicate ignores"""
2298.8.3 by Kent Gibson
Extended test cases to test bug 86451.
138
        ignores._set_user_ignores(
139
            ['foo', './bar', u'b\xe5z', 'dir1/', 'dir3\\'])
1836.1.14 by John Arbash Meinel
Adding a helper function that will only add patterns if they are missing.
140
2077.1.2 by Kent Gibson
Strip trailing slashes from ignore patterns (#4559).
141
        added = ignores.add_unique_user_ignores(
2298.8.3 by Kent Gibson
Extended test cases to test bug 86451.
142
            ['xxx', './bar', 'xxx', 'dir1/', 'dir2/', 'dir3\\'])
2077.1.2 by Kent Gibson
Strip trailing slashes from ignore patterns (#4559).
143
        self.assertEqual(['xxx', 'dir2'], added)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
144
        self.assertEqual(set(['foo', './bar', u'b\xe5z',
2298.8.3 by Kent Gibson
Extended test cases to test bug 86451.
145
                              'xxx', 'dir1', 'dir2', 'dir3']),
1836.1.14 by John Arbash Meinel
Adding a helper function that will only add patterns if they are missing.
146
                         ignores.get_user_ignores())
1836.1.28 by John Arbash Meinel
Add a function for adding runtime ignores.
147
148
149
class TestRuntimeIgnores(TestCase):
150
151
    def setUp(self):
6552.1.4 by Vincent Ladeuil
Remaining tests matching setup(self) that can be rewritten with super().
152
        super(TestRuntimeIgnores, self).setUp()
1836.1.28 by John Arbash Meinel
Add a function for adding runtime ignores.
153
154
        # For the purposes of these tests, we must have no
155
        # runtime ignores
4985.1.5 by Vincent Ladeuil
Deploying the new overrideAttr facility further reduces the complexity
156
        self.overrideAttr(ignores, '_runtime_ignores', set())
1836.1.28 by John Arbash Meinel
Add a function for adding runtime ignores.
157
158
    def test_add(self):
159
        """Test that we can add an entry to the list."""
160
        self.assertEqual(set(), ignores.get_runtime_ignores())
161
162
        ignores.add_runtime_ignores(['foo'])
163
        self.assertEqual(set(['foo']), ignores.get_runtime_ignores())
164
165
    def test_add_duplicate(self):
166
        """Adding the same ignore twice shouldn't add a new entry."""
167
        ignores.add_runtime_ignores(['foo', 'bar'])
168
        self.assertEqual(set(['foo', 'bar']), ignores.get_runtime_ignores())
169
170
        ignores.add_runtime_ignores(['bar'])
171
        self.assertEqual(set(['foo', 'bar']), ignores.get_runtime_ignores())
3528.2.1 by Jelmer Vernooij
Move functionality to add ignores to the ignore file into a separate function.
172
173
174
class TestTreeIgnores(TestCaseWithTransport):
5195.2.1 by Gordon Tyler
Fixed tree_ignores_add_patterns to not duplicate existing patterns in the ignore file.
175
    
176
    def assertPatternsEquals(self, patterns):
5195.2.8 by Gordon Tyler
Fixed preservation of existing line endings and added tests for that and Unicode handling.
177
        contents = open(".bzrignore", 'rU').read().strip().split('\n')
178
        self.assertEquals(sorted(patterns), sorted(contents))
3528.2.1 by Jelmer Vernooij
Move functionality to add ignores to the ignore file into a separate function.
179
180
    def test_new_file(self):
181
        tree = self.make_branch_and_tree(".")
182
        ignores.tree_ignores_add_patterns(tree, ["myentry"])
183
        self.assertTrue(tree.has_filename(".bzrignore"))
5195.2.1 by Gordon Tyler
Fixed tree_ignores_add_patterns to not duplicate existing patterns in the ignore file.
184
        self.assertPatternsEquals(["myentry"])
3528.2.1 by Jelmer Vernooij
Move functionality to add ignores to the ignore file into a separate function.
185
186
    def test_add_to_existing(self):
187
        tree = self.make_branch_and_tree(".")
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
188
        self.build_tree_contents([('.bzrignore', "myentry1\n")])
3528.2.1 by Jelmer Vernooij
Move functionality to add ignores to the ignore file into a separate function.
189
        tree.add([".bzrignore"])
190
        ignores.tree_ignores_add_patterns(tree, ["myentry2", "foo"])
5195.2.1 by Gordon Tyler
Fixed tree_ignores_add_patterns to not duplicate existing patterns in the ignore file.
191
        self.assertPatternsEquals(["myentry1", "myentry2", "foo"])
3528.2.1 by Jelmer Vernooij
Move functionality to add ignores to the ignore file into a separate function.
192
193
    def test_adds_ending_newline(self):
194
        tree = self.make_branch_and_tree(".")
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
195
        self.build_tree_contents([('.bzrignore', "myentry1")])
3528.2.1 by Jelmer Vernooij
Move functionality to add ignores to the ignore file into a separate function.
196
        tree.add([".bzrignore"])
197
        ignores.tree_ignores_add_patterns(tree, ["myentry2"])
5195.2.1 by Gordon Tyler
Fixed tree_ignores_add_patterns to not duplicate existing patterns in the ignore file.
198
        self.assertPatternsEquals(["myentry1", "myentry2"])
199
        text = open(".bzrignore", 'r').read()
200
        self.assertTrue(text.endswith('\r\n') or
201
                        text.endswith('\n') or
202
                        text.endswith('\r'))
3528.2.1 by Jelmer Vernooij
Move functionality to add ignores to the ignore file into a separate function.
203
5195.2.1 by Gordon Tyler
Fixed tree_ignores_add_patterns to not duplicate existing patterns in the ignore file.
204
    def test_does_not_add_dupe(self):
205
        tree = self.make_branch_and_tree(".")
206
        self.build_tree_contents([('.bzrignore', "myentry\n")])
207
        tree.add([".bzrignore"])
208
        ignores.tree_ignores_add_patterns(tree, ["myentry"])
209
        self.assertPatternsEquals(["myentry"])
5195.2.8 by Gordon Tyler
Fixed preservation of existing line endings and added tests for that and Unicode handling.
210
211
    def test_non_ascii(self):
212
        tree = self.make_branch_and_tree(".")
213
        self.build_tree_contents([('.bzrignore',
214
                                   u"myentry\u1234\n".encode('utf-8'))])
215
        tree.add([".bzrignore"])
216
        ignores.tree_ignores_add_patterns(tree, [u"myentry\u5678"])
217
        self.assertPatternsEquals([u"myentry\u1234".encode('utf-8'),
218
                                   u"myentry\u5678".encode('utf-8')])
219
220
    def test_crlf(self):
221
        tree = self.make_branch_and_tree(".")
222
        self.build_tree_contents([('.bzrignore', "myentry1\r\n")])
223
        tree.add([".bzrignore"])
224
        ignores.tree_ignores_add_patterns(tree, ["myentry2", "foo"])
225
        self.assertEquals(open('.bzrignore', 'rb').read(), 'myentry1\r\nmyentry2\r\nfoo\r\n')
226
        self.assertPatternsEquals(["myentry1", "myentry2", "foo"])