| OLD | NEW |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | 1 # Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import copy |
| 5 import unittest | 6 import unittest |
| 6 | 7 |
| 7 from crash.loglinear import feature | 8 from crash.loglinear import feature |
| 9 from crash.loglinear.feature import ChangedFile |
| 10 from crash.loglinear.feature import MetaFeatureValue |
| 11 from crash.loglinear.test.loglinear_testcase import Feature0 |
| 12 from crash.loglinear.test.loglinear_testcase import Feature1 |
| 13 from crash.loglinear.test.loglinear_testcase import Feature2 |
| 14 from crash.loglinear.test.loglinear_testcase import Feature3 |
| 15 from crash.loglinear.test.loglinear_testcase import Feature4 |
| 8 from crash.loglinear.test.loglinear_testcase import LoglinearTestCase | 16 from crash.loglinear.test.loglinear_testcase import LoglinearTestCase |
| 9 import libs.math.logarithms as lmath | 17 import libs.math.logarithms as lmath |
| 10 | 18 |
| 11 _MAXIMUM = 50. | 19 _MAXIMUM = 50. |
| 12 | 20 |
| 13 | 21 |
| 14 class ChangelistFeatureTest(unittest.TestCase): | 22 class ChangelistFeatureTest(unittest.TestCase): |
| 15 | 23 |
| 16 def testLinearlyScaledIsZero(self): | 24 def testLinearlyScaledIsZero(self): |
| 17 """Test that ``LinearlyScaled`` takes 0 to 1.""" | 25 """Test that ``LinearlyScaled`` takes 0 to 1.""" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 34 """Test that ``LogLinearlyScaled`` works on middling values.""" | 42 """Test that ``LogLinearlyScaled`` works on middling values.""" |
| 35 self.assertEqual( | 43 self.assertEqual( |
| 36 lmath.log((_MAXIMUM - 42.) / _MAXIMUM), | 44 lmath.log((_MAXIMUM - 42.) / _MAXIMUM), |
| 37 feature.LogLinearlyScaled(42., _MAXIMUM)) | 45 feature.LogLinearlyScaled(42., _MAXIMUM)) |
| 38 | 46 |
| 39 def testLogLinearlyScaledIsOverMax(self): | 47 def testLogLinearlyScaledIsOverMax(self): |
| 40 """Test that ``LogLinearlyScaled`` takes values over the max to log(0).""" | 48 """Test that ``LogLinearlyScaled`` takes values over the max to log(0).""" |
| 41 self.assertEqual(lmath.LOG_ZERO, feature.LogLinearlyScaled(42., 10.)) | 49 self.assertEqual(lmath.LOG_ZERO, feature.LogLinearlyScaled(42., 10.)) |
| 42 | 50 |
| 43 | 51 |
| 44 class FeatureFunctionTest(LoglinearTestCase): | 52 class MetaFeatureValueTest(unittest.TestCase): |
| 45 | 53 |
| 46 def testFeatureFunction(self): | 54 def setUp(self): |
| 47 """Test that ``FeatureFunction`` obeys the equality its docstring says.""" | 55 super(MetaFeatureValueTest, self).setUp() |
| 56 self.feature = MetaFeatureValue( |
| 57 'dummy', {feature.name: feature(3)(False) |
| 58 for feature in [Feature0(), Feature1()]}) |
| 59 |
| 60 def testEqaul(self): |
| 61 """Tests overriding ``__eq__`` and ``__ne__``.""" |
| 62 copy_meta_feature = copy.deepcopy(self.feature) |
| 63 self.assertTrue(self.feature == copy_meta_feature) |
| 64 copy_meta_feature._name = 'dummy2' |
| 65 self.assertTrue(self.feature != copy_meta_feature) |
| 66 |
| 67 def testLen(self): |
| 68 """Tests overriding ``__len__``.""" |
| 69 self.assertEqual(len(self.feature), 2) |
| 70 |
| 71 def testFormatReasons(self): |
| 72 """Tests ``FormatReasons`` returnes a list of formated reasons.""" |
| 73 self.assertEqual(self.feature.reason, |
| 74 'Feature0: 1.000000 -- reason0\n' |
| 75 'Feature1: 0.000000 -- reason1') |
| 76 self.assertEqual(self.feature.reason, self.feature._reason) |
| 77 |
| 78 def testAggregateChangedFilesAggregates(self): |
| 79 """Test that ``AggregateChangedFiles`` does aggregate reasons per file. |
| 80 |
| 81 In the main/inner loop of ``AggregateChangedFiles``: if multiple |
| 82 features all blame the same file change, we try to aggregate those |
| 83 reasons so that we only report the file once (with all reasons). None |
| 84 of the other tests here actually check the case where the same file |
| 85 is blamed multiple times, so we check that here. |
| 86 |
| 87 In particular, we provide the same ``FeatureValue`` twice, and |
| 88 hence the same ``ChangedFile`` twice; so we should get back a single |
| 89 ``ChangedFile`` but with the ``reasons`` fields concatenated. |
| 90 """ |
| 91 self.assertListEqual(self.feature.changed_files, |
| 92 [ChangedFile(name='a.cc', |
| 93 blame_url=None, |
| 94 reasons=['file_reason0']), |
| 95 ChangedFile(name='b.cc', |
| 96 blame_url=None, |
| 97 reasons=['file_reason0', |
| 98 'file_reason1'])]) |
| 99 self.assertEqual(self.feature.changed_files, |
| 100 self.feature._changed_files) |
| 101 |
| 102 |
| 103 class WrapperMetaFeatureTest(LoglinearTestCase): |
| 104 |
| 105 def testWrapperMetaFeatureWrapsIndependentFeatures(self): |
| 48 for x in self._X: | 106 for x in self._X: |
| 49 for y in self._Y(x): | 107 for y in self._Y(x): |
| 50 for f in self._feature_list: | 108 self.assertTrue( |
| 51 self.assertEqual(f(x)(y), self._feature_function(x)(y)[f.name]) | 109 self._meta_feature(x)(y) == |
| 110 MetaFeatureValue('WrapperFeature', |
| 111 {'Feature0': Feature0()(x)(y), |
| 112 'Feature1': Feature1()(x)(y), |
| 113 'Feature2': Feature2()(x)(y), |
| 114 'WrapperFeature': MetaFeatureValue( |
| 115 'WrapperFeature', |
| 116 {'Feature3': Feature3()(x)(y), |
| 117 'Feature4': Feature4()(x)(y)})})) |
| OLD | NEW |