--- a/compare_locales/compare.py
+++ b/compare_locales/compare.py
@@ -189,36 +189,38 @@ class Observer(object):
def toJSON(self):
# Don't export file stats, even if we collected them.
# Those are not part of the data we use toJSON for.
return {
'summary': self._dictify(self.summary),
'details': self.details.toJSON()
}
+ def updateStats(self, file, stats):
+ # in multi-project scenarios, this file might not be ours,
+ # check that.
+ if (self.filter is not None and
+ self.filter(file) in (None, 'ignore')):
+ return
+ for category, value in stats.iteritems():
+ self.summary[file.locale][category] += value
+ if self.file_stats is None:
+ return
+ if 'missingInFiles' in stats:
+ # keep track of how many strings are in a missing file
+ # we got the {'missingFile': 'error'} from the notify pass
+ self.details[file]['strings'] = stats['missingInFiles']
+ # missingInFiles should just be "missing" in file stats
+ self.file_stats[file.locale][file.localpath]['missing'] = \
+ stats['missingInFiles']
+ return # there are no other stats for missing files
+ self.file_stats[file.locale][file.localpath].update(stats)
+
def notify(self, category, file, data):
- rv = "error"
- if category in self.stat_cats:
- # these get called post reporting just for stats
- # return "error" to forward them to other other_observers
- # in multi-project scenarios, this file might not be ours,
- # check that.
- if (self.filter is not None and
- self.filter(file) in (None, 'ignore')):
- return 'ignore'
- self.summary[file.locale][category] += data
- if self.file_stats is not None:
- # missingInFiles should just be "missing" in file stats
- cat = category if category != 'missingInFiles' else 'missing'
- self.file_stats[file.locale][file.localpath][cat] = data
- # keep track of how many strings are in a missing file
- # we got the {'missingFile': 'error'} from the first pass
- if category == 'missingInFiles':
- self.details[file]['strings'] = data
- return "error"
+ rv = 'error'
if category in ['missingFile', 'obsoleteFile']:
if self.filter is not None:
rv = self.filter(file)
if rv != "ignore":
self.details[file][category] = rv
return rv
if category in ['missingEntity', 'obsoleteEntity']:
if self.filter is not None:
@@ -421,16 +423,23 @@ class ContentComparer:
for obs in self.other_observers:
# non-filtering other_observers, ignore results
obs.notify(category, file, data)
if 'error' in rvs:
return 'error'
assert len(rvs) == 1
return rvs.pop()
+ def updateStats(self, file, stats):
+ """Check observer for the found data, and if it's
+ not to ignore, notify other_observers.
+ """
+ for observer in self.observers + self.other_observers:
+ observer.updateStats(file, stats)
+
def remove(self, obsolete):
self.notify('obsoleteFile', obsolete, None)
pass
def compare(self, ref_file, l10n, extra_tests=None):
try:
p = parser.getParser(ref_file.file)
except UserWarning:
@@ -520,33 +529,32 @@ class ContentComparer:
_l, col = l10nent.value_position(pos)
# skip error entities when merging
if tp == 'error' and self.merge_stage is not None:
skips.append(l10nent)
self.notify(tp, l10n,
u"%s at line %d, column %d for %s" %
(msg, _l, col, refent.key))
pass
- if missing:
- self.notify('missing', l10n, missing)
if self.merge_stage is not None and (missings or skips):
self.merge(
ref[0], ref[1], ref_file,
l10n, missings, skips, l10n_ctx,
p.canMerge, p.encoding)
- if report:
- self.notify('report', l10n, report)
- if obsolete:
- self.notify('obsolete', l10n, obsolete)
- if changed:
- self.notify('changed', l10n, changed)
- if unchanged:
- self.notify('unchanged', l10n, unchanged)
- if keys:
- self.notify('keys', l10n, keys)
+ stats = {}
+ for cat, value in (
+ ('missing', missing),
+ ('report', report),
+ ('obsolete', obsolete),
+ ('changed', changed),
+ ('unchanged', unchanged),
+ ('keys', keys)):
+ if value:
+ stats[cat] = value
+ self.updateStats(l10n, stats)
pass
def add(self, orig, missing):
if self.notify('missingFile', missing, None) == "ignore":
# filter said that we don't need this file, don't count it
return
f = orig
try:
@@ -554,17 +562,17 @@ class ContentComparer:
except UserWarning:
return
try:
p.readContents(f.getContents())
entities, map = p.parse()
except Exception, e:
self.notify('error', f, str(e))
return
- self.notify('missingInFiles', missing, len(map))
+ self.updateStats(missing, {'missingInFiles': len(map)})
def doUnchanged(self, entity):
# overload this if needed
pass
def doChanged(self, file, ref_entity, l10n_entity):
# overload this if needed
pass
--- a/compare_locales/tests/test_compare.py
+++ b/compare_locales/tests/test_compare.py
@@ -91,17 +91,17 @@ two/other
)
class TestObserver(unittest.TestCase):
def test_simple(self):
obs = compare.Observer()
f = paths.File('/some/real/sub/path', 'sub/path', locale='de')
obs.notify('missingEntity', f, ['one', 'two'])
- obs.notify('missing', f, 15)
+ obs.updateStats(f, {'missing': 15})
self.assertDictEqual(obs.toJSON(), {
'summary': {
'de': {
'missing': 15
}
},
'details': {
'children': [
@@ -116,17 +116,17 @@ class TestObserver(unittest.TestCase):
self.assertDictEqual(clone.details.toJSON(), obs.details.toJSON())
self.assertIsNone(clone.file_stats)
def test_module(self):
obs = compare.Observer(file_stats=True)
f = paths.File('/some/real/sub/path', 'path',
module='sub', locale='de')
obs.notify('missingEntity', f, ['one', 'two'])
- obs.notify('missing', f, 15)
+ obs.updateStats(f, {'missing': 15})
self.assertDictEqual(obs.toJSON(), {
'summary': {
'de': {
'missing': 15
}
},
'details': {
'children': [
@@ -147,17 +147,17 @@ class TestObserver(unittest.TestCase):
self.assertDictEqual(clone.summary, obs.summary)
self.assertDictEqual(clone.details.toJSON(), obs.details.toJSON())
self.assertDictEqual(clone.file_stats, obs.file_stats)
def test_file_stats(self):
obs = compare.Observer(file_stats=True)
f = paths.File('/some/real/sub/path', 'sub/path', locale='de')
obs.notify('missingEntity', f, ['one', 'two'])
- obs.notify('missing', f, 15)
+ obs.updateStats(f, {'missing': 15})
self.assertDictEqual(obs.toJSON(), {
'summary': {
'de': {
'missing': 15
}
},
'details': {
'children': [