mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 11:55:49 +00:00
Bug 1063414 - Add infrastructure to follow what the current file being processed is in a Context. r=gps
This commit is contained in:
parent
c0676d9dc8
commit
be7f345453
@ -78,18 +78,63 @@ class Context(KeyedDefaultDict):
|
||||
def __init__(self, allowed_variables={}, config=None):
|
||||
self._allowed_variables = allowed_variables
|
||||
self.main_path = None
|
||||
self.all_paths = set()
|
||||
self.current_path = None
|
||||
# There aren't going to be enough paths for the performance of scanning
|
||||
# a list to be a problem.
|
||||
self._all_paths = []
|
||||
self.config = config
|
||||
self.executed_time = 0
|
||||
KeyedDefaultDict.__init__(self, self._factory)
|
||||
|
||||
def push_source(self, path):
|
||||
"""Adds the given path as source of the data from this context and make
|
||||
it the current path for the context."""
|
||||
assert os.path.isabs(path)
|
||||
if not self.main_path:
|
||||
self.main_path = path
|
||||
else:
|
||||
# Callers shouldn't push after main_path has been popped.
|
||||
assert self.current_path
|
||||
self.current_path = path
|
||||
# The same file can be pushed twice, so don't remove any previous
|
||||
# occurrence.
|
||||
self._all_paths.append(path)
|
||||
|
||||
def pop_source(self):
|
||||
"""Get back to the previous current path for the context."""
|
||||
assert self.main_path
|
||||
assert self.current_path
|
||||
last = self._all_paths.pop()
|
||||
# Keep the popped path in the list of all paths, but before the main
|
||||
# path so that it's not popped again.
|
||||
self._all_paths.insert(0, last)
|
||||
if last == self.main_path:
|
||||
self.current_path = None
|
||||
else:
|
||||
self.current_path = self._all_paths[-1]
|
||||
return last
|
||||
|
||||
def add_source(self, path):
|
||||
"""Adds the given path as source of the data from this context."""
|
||||
assert os.path.isabs(path)
|
||||
|
||||
if not self.main_path:
|
||||
self.main_path = path
|
||||
self.all_paths.add(path)
|
||||
self.main_path = self.current_path = path
|
||||
# Insert at the beginning of the list so that it's always before the
|
||||
# main path.
|
||||
if path not in self._all_paths:
|
||||
self._all_paths.insert(0, path)
|
||||
|
||||
@property
|
||||
def all_paths(self):
|
||||
"""Returns all paths ever added to the context."""
|
||||
return set(self._all_paths)
|
||||
|
||||
@property
|
||||
def source_stack(self):
|
||||
"""Returns the current stack of pushed sources."""
|
||||
if not self.current_path:
|
||||
return []
|
||||
return self._all_paths[self._all_paths.index(self.main_path):]
|
||||
|
||||
@memoized_property
|
||||
def objdir(self):
|
||||
|
@ -2,6 +2,7 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from mozunit import main
|
||||
@ -95,6 +96,110 @@ class TestContext(unittest.TestCase):
|
||||
self.assertEqual(test['foo'], 42)
|
||||
self.assertEqual(test['baz'], { 'c': 3, 'd': 4 })
|
||||
|
||||
def test_paths(self):
|
||||
test = Context()
|
||||
|
||||
# Newly created context has no paths.
|
||||
self.assertIsNone(test.main_path)
|
||||
self.assertIsNone(test.current_path)
|
||||
self.assertEqual(test.all_paths, set())
|
||||
self.assertEqual(test.source_stack, [])
|
||||
|
||||
foo = os.path.abspath('foo')
|
||||
test.add_source(foo)
|
||||
|
||||
# Adding the first source makes it the main and current path.
|
||||
self.assertEqual(test.main_path, foo)
|
||||
self.assertEqual(test.current_path, foo)
|
||||
self.assertEqual(test.all_paths, set([foo]))
|
||||
self.assertEqual(test.source_stack, [foo])
|
||||
|
||||
bar = os.path.abspath('bar')
|
||||
test.add_source(bar)
|
||||
|
||||
# Adding the second source makes leaves main and current paths alone.
|
||||
self.assertEqual(test.main_path, foo)
|
||||
self.assertEqual(test.current_path, foo)
|
||||
self.assertEqual(test.all_paths, set([bar, foo]))
|
||||
self.assertEqual(test.source_stack, [foo])
|
||||
|
||||
qux = os.path.abspath('qux')
|
||||
test.push_source(qux)
|
||||
|
||||
# Pushing a source makes it the current path
|
||||
self.assertEqual(test.main_path, foo)
|
||||
self.assertEqual(test.current_path, qux)
|
||||
self.assertEqual(test.all_paths, set([bar, foo, qux]))
|
||||
self.assertEqual(test.source_stack, [foo, qux])
|
||||
|
||||
hoge = os.path.abspath('hoge')
|
||||
test.push_source(hoge)
|
||||
self.assertEqual(test.main_path, foo)
|
||||
self.assertEqual(test.current_path, hoge)
|
||||
self.assertEqual(test.all_paths, set([bar, foo, hoge, qux]))
|
||||
self.assertEqual(test.source_stack, [foo, qux, hoge])
|
||||
|
||||
fuga = os.path.abspath('fuga')
|
||||
|
||||
# Adding a source after pushing doesn't change the source stack
|
||||
test.add_source(fuga)
|
||||
self.assertEqual(test.main_path, foo)
|
||||
self.assertEqual(test.current_path, hoge)
|
||||
self.assertEqual(test.all_paths, set([bar, foo, fuga, hoge, qux]))
|
||||
self.assertEqual(test.source_stack, [foo, qux, hoge])
|
||||
|
||||
# Adding a source twice doesn't change anything
|
||||
test.add_source(qux)
|
||||
self.assertEqual(test.main_path, foo)
|
||||
self.assertEqual(test.current_path, hoge)
|
||||
self.assertEqual(test.all_paths, set([bar, foo, fuga, hoge, qux]))
|
||||
self.assertEqual(test.source_stack, [foo, qux, hoge])
|
||||
|
||||
last = test.pop_source()
|
||||
|
||||
# Popping a source returns the last pushed one, not the last added one.
|
||||
self.assertEqual(last, hoge)
|
||||
self.assertEqual(test.main_path, foo)
|
||||
self.assertEqual(test.current_path, qux)
|
||||
self.assertEqual(test.all_paths, set([bar, foo, fuga, hoge, qux]))
|
||||
self.assertEqual(test.source_stack, [foo, qux])
|
||||
|
||||
last = test.pop_source()
|
||||
self.assertEqual(last, qux)
|
||||
self.assertEqual(test.main_path, foo)
|
||||
self.assertEqual(test.current_path, foo)
|
||||
self.assertEqual(test.all_paths, set([bar, foo, fuga, hoge, qux]))
|
||||
self.assertEqual(test.source_stack, [foo])
|
||||
|
||||
# Popping the main path is allowed.
|
||||
last = test.pop_source()
|
||||
self.assertEqual(last, foo)
|
||||
self.assertEqual(test.main_path, foo)
|
||||
self.assertIsNone(test.current_path)
|
||||
self.assertEqual(test.all_paths, set([bar, foo, fuga, hoge, qux]))
|
||||
self.assertEqual(test.source_stack, [])
|
||||
|
||||
# Popping past the main path asserts.
|
||||
with self.assertRaises(AssertionError):
|
||||
test.pop_source()
|
||||
|
||||
# Pushing after the main path was popped asserts.
|
||||
with self.assertRaises(AssertionError):
|
||||
test.push_source(foo)
|
||||
|
||||
test = Context()
|
||||
test.push_source(foo)
|
||||
test.push_source(bar)
|
||||
|
||||
# Pushing the same file twice is allowed.
|
||||
test.push_source(bar)
|
||||
test.push_source(foo)
|
||||
self.assertEqual(last, foo)
|
||||
self.assertEqual(test.main_path, foo)
|
||||
self.assertEqual(test.current_path, foo)
|
||||
self.assertEqual(test.all_paths, set([bar, foo]))
|
||||
self.assertEqual(test.source_stack, [foo, bar, bar, foo])
|
||||
|
||||
|
||||
class TestSymbols(unittest.TestCase):
|
||||
def _verify_doc(self, doc):
|
||||
|
Loading…
Reference in New Issue
Block a user