1#!/usr/bin/env python
2# Copyright (c) 2012 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6from copy import deepcopy
7from file_system import FileNotFoundError, StatInfo
8from test_file_system import TestFileSystem, MoveTo
9import unittest
10
11
12_TEST_DATA = {
13  '404.html': '404.html contents',
14  'apps': {
15    'a11y.html': 'a11y.html contents',
16    'about_apps.html': 'about_apps.html contents',
17    'fakedir': {
18      'file.html': 'file.html contents'
19    }
20  },
21  'extensions': {
22    'activeTab.html': 'activeTab.html contents',
23    'alarms.html': 'alarms.html contents'
24  }
25}
26
27
28def _Get(fn):
29  '''Returns a function which calls Future.Get on the result of |fn|.
30  '''
31  return lambda *args: fn(*args).Get()
32
33
34class TestFileSystemTest(unittest.TestCase):
35  def testEmptyFileSystem(self):
36    self._TestMetasyntacticPaths(TestFileSystem({}))
37
38  def testNonemptyFileNotFoundErrors(self):
39    fs = TestFileSystem(deepcopy(_TEST_DATA))
40    self._TestMetasyntacticPaths(fs)
41    self.assertRaises(FileNotFoundError, _Get(fs.Read), ['404.html/'])
42    self.assertRaises(FileNotFoundError, _Get(fs.Read), ['apps/foo/'])
43    self.assertRaises(FileNotFoundError, _Get(fs.Read), ['apps/foo.html'])
44    self.assertRaises(FileNotFoundError, _Get(fs.Read), ['apps/foo.html'])
45    self.assertRaises(FileNotFoundError, _Get(fs.Read), ['apps/foo/',
46                                                         'apps/foo.html'])
47    self.assertRaises(FileNotFoundError, _Get(fs.Read), ['apps/foo/',
48                                                         'apps/a11y.html'])
49
50  def _TestMetasyntacticPaths(self, fs):
51    self.assertRaises(FileNotFoundError, _Get(fs.Read), ['foo'])
52    self.assertRaises(FileNotFoundError, _Get(fs.Read), ['bar/'])
53    self.assertRaises(FileNotFoundError, _Get(fs.Read), ['bar/baz'])
54    self.assertRaises(FileNotFoundError, _Get(fs.Read), ['foo',
55                                                         'bar/',
56                                                         'bar/baz'])
57    self.assertRaises(FileNotFoundError, fs.Stat, 'foo')
58    self.assertRaises(FileNotFoundError, fs.Stat, 'bar/')
59    self.assertRaises(FileNotFoundError, fs.Stat, 'bar/baz')
60
61  def testNonemptySuccess(self):
62    fs = TestFileSystem(deepcopy(_TEST_DATA))
63    self.assertEqual('404.html contents', fs.ReadSingle('404.html').Get())
64    self.assertEqual('a11y.html contents',
65                     fs.ReadSingle('apps/a11y.html').Get())
66    self.assertEqual(['404.html', 'apps/', 'extensions/'],
67                     sorted(fs.ReadSingle('').Get()))
68    self.assertEqual(['a11y.html', 'about_apps.html', 'fakedir/'],
69                     sorted(fs.ReadSingle('apps/').Get()))
70
71  def testReadFiles(self):
72    fs = TestFileSystem(deepcopy(_TEST_DATA))
73    self.assertEqual('404.html contents',
74                     fs.ReadSingle('404.html').Get())
75    self.assertEqual('a11y.html contents',
76                     fs.ReadSingle('apps/a11y.html').Get())
77    self.assertEqual('file.html contents',
78                     fs.ReadSingle('apps/fakedir/file.html').Get())
79
80  def testReadDirs(self):
81    fs = TestFileSystem(deepcopy(_TEST_DATA))
82    self.assertEqual(['404.html', 'apps/', 'extensions/'],
83                     sorted(fs.ReadSingle('').Get()))
84    self.assertEqual(['a11y.html', 'about_apps.html', 'fakedir/'],
85                     sorted(fs.ReadSingle('apps/').Get()))
86    self.assertEqual(['file.html'], fs.ReadSingle('apps/fakedir/').Get())
87
88  def testStat(self):
89    fs = TestFileSystem(deepcopy(_TEST_DATA))
90    self.assertRaises(FileNotFoundError, fs.Stat, 'foo')
91    self.assertRaises(FileNotFoundError, fs.Stat, '404.html/')
92    self.assertEquals(StatInfo('0', child_versions={
93                        '404.html': '0',
94                        'apps/': '0',
95                        'extensions/': '0',
96                      }), fs.Stat(''))
97    self.assertEquals(StatInfo('0'), fs.Stat('404.html'))
98    self.assertEquals(StatInfo('0', child_versions={
99                        'activeTab.html': '0',
100                        'alarms.html': '0',
101                      }), fs.Stat('extensions/'))
102
103    fs.IncrementStat()
104    self.assertEquals(StatInfo('1', child_versions={
105                        '404.html': '1',
106                        'apps/': '1',
107                        'extensions/': '1',
108                      }), fs.Stat(''))
109    self.assertEquals(StatInfo('1'), fs.Stat('404.html'))
110    self.assertEquals(StatInfo('1', child_versions={
111                        'activeTab.html': '1',
112                        'alarms.html': '1',
113                      }), fs.Stat('extensions/'))
114
115    fs.IncrementStat(path='404.html')
116    self.assertEquals(StatInfo('2', child_versions={
117                        '404.html': '2',
118                        'apps/': '1',
119                        'extensions/': '1',
120                      }), fs.Stat(''))
121    self.assertEquals(StatInfo('2'), fs.Stat('404.html'))
122    self.assertEquals(StatInfo('1', child_versions={
123                        'activeTab.html': '1',
124                        'alarms.html': '1',
125                      }), fs.Stat('extensions/'))
126
127    fs.IncrementStat()
128    self.assertEquals(StatInfo('3', child_versions={
129                        '404.html': '3',
130                        'apps/': '2',
131                        'extensions/': '2',
132                      }), fs.Stat(''))
133    self.assertEquals(StatInfo('3'), fs.Stat('404.html'))
134    self.assertEquals(StatInfo('2', child_versions={
135                        'activeTab.html': '2',
136                        'alarms.html': '2',
137                      }), fs.Stat('extensions/'))
138
139    # It doesn't make sense to increment the version of directories. Directory
140    # versions are derived from the version of files within them.
141    self.assertRaises(ValueError, fs.IncrementStat, path='')
142    self.assertRaises(ValueError, fs.IncrementStat, path='extensions/')
143    self.assertEquals(StatInfo('3', child_versions={
144                        '404.html': '3',
145                        'apps/': '2',
146                        'extensions/': '2',
147                      }), fs.Stat(''))
148    self.assertEquals(StatInfo('3'), fs.Stat('404.html'))
149    self.assertEquals(StatInfo('2', child_versions={
150                        'activeTab.html': '2',
151                        'alarms.html': '2',
152                      }), fs.Stat('extensions/'))
153
154    fs.IncrementStat(path='extensions/alarms.html')
155    self.assertEquals(StatInfo('3', child_versions={
156                        '404.html': '3',
157                        'apps/': '2',
158                        'extensions/': '3',
159                      }), fs.Stat(''))
160    self.assertEquals(StatInfo('3'), fs.Stat('404.html'))
161    self.assertEquals(StatInfo('3', child_versions={
162                        'activeTab.html': '2',
163                        'alarms.html': '3',
164                      }), fs.Stat('extensions/'))
165
166    fs.IncrementStat(path='extensions/activeTab.html', by=3)
167    self.assertEquals(StatInfo('5', child_versions={
168                        '404.html': '3',
169                        'apps/': '2',
170                        'extensions/': '5',
171                      }), fs.Stat(''))
172    self.assertEquals(StatInfo('3'), fs.Stat('404.html'))
173    self.assertEquals(StatInfo('5', child_versions={
174                        'activeTab.html': '5',
175                        'alarms.html': '3',
176                      }), fs.Stat('extensions/'))
177
178  def testMoveTo(self):
179    self.assertEqual({'foo': {'a': 'b', 'c': 'd'}},
180                     MoveTo('foo/', {'a': 'b', 'c': 'd'}))
181    self.assertEqual({'foo': {'bar': {'a': 'b', 'c': 'd'}}},
182                     MoveTo('foo/bar/', {'a': 'b', 'c': 'd'}))
183    self.assertEqual({'foo': {'bar': {'baz': {'a': 'b'}}}},
184                     MoveTo('foo/bar/baz/', {'a': 'b'}))
185
186
187if __name__ == '__main__':
188  unittest.main()
189